2424import logging
2525import os
2626import sys
27- import xml .etree .ElementTree as ET
2827from gettext import gettext
2928from pathlib import Path
30- from typing import List , Optional , Tuple
29+ from typing import List , Literal , Optional , Tuple
3130
3231import click
32+ import lxml .etree as ET
3333import yaml
3434from click_default_group import DefaultGroup
3535
3636from pynxtools .dataconverter import helpers
37+ from pynxtools .dataconverter .nexus_tree import generate_tree_from
3738from pynxtools .dataconverter .readers .base .reader import BaseReader
3839from pynxtools .dataconverter .template import Template
40+ from pynxtools .dataconverter .validation import validate_dict_against
3941from pynxtools .dataconverter .writer import Writer
4042from pynxtools .nexus import nexus
4143
@@ -99,61 +101,11 @@ def get_names_of_all_readers() -> List[str]:
99101 return sorted (all_readers + plugins )
100102
101103
102- def get_nxdl_root_and_path (nxdl : str ):
103- """Get xml root element and file path from nxdl name e.g. NXapm.
104-
105- Parameters
106- ----------
107- nxdl: str
108- Name of nxdl file e.g. NXapm from NXapm.nxdl.xml.
109-
110- Returns
111- -------
112- ET.root
113- Root element of nxdl file.
114- str
115- Path of nxdl file.
116-
117- Raises
118- ------
119- FileNotFoundError
120- Error if no file with the given nxdl name is found.
121- """
122- # Reading in the NXDL and generating a template
123- definitions_path = nexus .get_nexus_definitions_path ()
124- if nxdl == "NXtest" :
125- nxdl_f_path = os .path .join (
126- f"{ os .path .abspath (os .path .dirname (__file__ ))} /../../" ,
127- "tests" ,
128- "data" ,
129- "dataconverter" ,
130- "NXtest.nxdl.xml" ,
131- )
132- elif nxdl == "NXroot" :
133- nxdl_f_path = os .path .join (definitions_path , "base_classes" , "NXroot.nxdl.xml" )
134- else :
135- nxdl_f_path = os .path .join (
136- definitions_path , "contributed_definitions" , f"{ nxdl } .nxdl.xml"
137- )
138- if not os .path .exists (nxdl_f_path ):
139- nxdl_f_path = os .path .join (
140- definitions_path , "applications" , f"{ nxdl } .nxdl.xml"
141- )
142- if not os .path .exists (nxdl_f_path ):
143- nxdl_f_path = os .path .join (
144- definitions_path , "base_classes" , f"{ nxdl } .nxdl.xml"
145- )
146- if not os .path .exists (nxdl_f_path ):
147- raise FileNotFoundError (f"The nxdl file, { nxdl } , was not found." )
148-
149- return ET .parse (nxdl_f_path ).getroot (), nxdl_f_path
150-
151-
152104def transfer_data_into_template (
153105 input_file ,
154106 reader ,
155107 nxdl_name ,
156- nxdl_root : Optional [ET .Element ] = None ,
108+ nxdl_root : Optional [ET ._Element ] = None ,
157109 skip_verify : bool = False ,
158110 ** kwargs ,
159111):
@@ -182,7 +134,7 @@ def transfer_data_into_template(
182134
183135 """
184136 if nxdl_root is None :
185- nxdl_root , _ = get_nxdl_root_and_path (nxdl = nxdl_name )
137+ nxdl_root , _ = helpers . get_nxdl_root_and_path (nxdl = nxdl_name )
186138
187139 template = Template ()
188140 helpers .generate_template_from_nxdl (nxdl_root , template )
@@ -204,14 +156,24 @@ def transfer_data_into_template(
204156 "The chosen NXDL isn't supported by the selected reader."
205157 )
206158
159+ if "ignore_undocumented" in kwargs :
160+ ignore_undocumented = kwargs ["ignore_undocumented" ]
161+ del kwargs ["ignore_undocumented" ]
162+ else :
163+ ignore_undocumented = False
164+
207165 data = data_reader ().read ( # type: ignore[operator]
208166 template = Template (template ), file_paths = input_file , ** kwargs
209167 )
210168 entry_names = data .get_all_entry_names ()
211169 for entry_name in entry_names :
212170 helpers .write_nexus_def_to_entry (data , entry_name , nxdl_name )
213171 if not skip_verify :
214- helpers .validate_data_dict (template , data , nxdl_root )
172+ validate_dict_against (
173+ nxdl_name ,
174+ data ,
175+ ignore_undocumented = ignore_undocumented ,
176+ )
215177 return data
216178
217179
@@ -254,7 +216,7 @@ def convert(
254216 None.
255217 """
256218
257- nxdl_root , nxdl_f_path = get_nxdl_root_and_path (nxdl )
219+ nxdl_root , nxdl_f_path = helpers . get_nxdl_root_and_path (nxdl )
258220
259221 data = transfer_data_into_template (
260222 input_file = input_file ,
@@ -366,6 +328,12 @@ def main_cli():
366328 default = False ,
367329 help = "Shows a log output for all undocumented fields" ,
368330)
331+ @click .option (
332+ "--ignore-undocumented" ,
333+ is_flag = True ,
334+ default = False ,
335+ help = "Ignore all undocumented fields during validation." ,
336+ )
369337@click .option (
370338 "--skip-verify" ,
371339 is_flag = True ,
@@ -386,6 +354,7 @@ def convert_cli(
386354 output : str ,
387355 fair : bool ,
388356 params_file : str ,
357+ ignore_undocumented : bool ,
389358 undocumented : bool ,
390359 skip_verify : bool ,
391360 mapping : str ,
@@ -435,6 +404,7 @@ def convert_cli(
435404 fair ,
436405 undocumented ,
437406 skip_verify ,
407+ ignore_undocumented = ignore_undocumented ,
438408 )
439409 except FileNotFoundError as exc :
440410 raise click .BadParameter (
@@ -472,21 +442,24 @@ def write_to_file(text):
472442 f .write (text )
473443 f .close ()
474444
475- print_or_write = lambda txt : write_to_file ( txt ) if output else print ( txt )
445+ tree = generate_tree_from ( nxdl )
476446
477- nxdl_root , nxdl_f_path = get_nxdl_root_and_path (nxdl )
478- template = Template ()
479- helpers .generate_template_from_nxdl (nxdl_root , template )
447+ print_or_write = lambda txt : write_to_file (txt ) if output else print (txt )
480448
449+ level : Literal ["required" , "recommended" , "optional" ] = "optional"
481450 if required :
482- template = Template (template .get_optionality ("required" ))
451+ level = "required"
452+ reqs = tree .required_fields_and_attrs_names (level = level )
453+ template = {
454+ helpers .convert_nxdl_path_dict_to_data_converter_dict (req ): None for req in reqs
455+ }
483456
484457 if pythonic :
485458 print_or_write (str (template ))
486459 return
487460 print_or_write (
488461 json .dumps (
489- template . get_accumulated_dict () ,
462+ template ,
490463 indent = 4 ,
491464 sort_keys = True ,
492465 ensure_ascii = False ,
0 commit comments