33
44import datetime
55import os .path
6+ import xml
67from xml .etree .ElementTree import ElementTree , ParseError
78
89import xmlschema
10+ import xmltodict
911
1012from adif_file .__version__ import __version__ as __version_str__
1113
@@ -32,40 +34,51 @@ class XmlSyntaxError(SyntaxError):
3234 pass
3335
3436
35- def load (file_name : str ) -> dict :
37+ def loads (adx_data : str , validate : bool = False ) -> dict :
38+ """Load ADX content to dictionary
39+ The ADX is not validated to conform to the standard
40+
41+ :param adx_data: the ADX content
42+ :param validate: validate the ADX against the genereic XSD (very slow)
43+ :return: the ADX as a dict
44+ """
45+
46+ if validate :
47+ try :
48+ ADX_IMPORT_SCHEMA .validate (adx_data )
49+ except ParseError as exc :
50+ raise XmlSyntaxError (str (exc )) from None
51+ except xmlschema .validators .exceptions .XMLSchemaChildrenValidationError as exc :
52+ raise UndefinedElementException (f'in { exc .elem .tag } ' ) from None
53+ except xmlschema .validators .exceptions .XMLSchemaValidationError as exc :
54+ raise MalformedValueException (f'Field "{ exc .elem .tag } ": { exc .reason } ' ) from None
55+
56+ try :
57+ data_dict = xmltodict .parse (adx_data , cdata_key = '$' )
58+ data_dict = data_dict ['ADX' ]
59+ if ('RECORDS' in data_dict and data_dict ['RECORDS' ] and
60+ 'RECORD' in data_dict ['RECORDS' ] and data_dict ['RECORDS' ]['RECORD' ]):
61+ data_dict ['RECORDS' ] = data_dict ['RECORDS' ]['RECORD' ]
62+ else :
63+ data_dict ['RECORDS' ] = []
64+ return data_dict
65+ except xml .parsers .expat .ExpatError as exc :
66+ raise XmlSyntaxError (str (exc )) from None
67+
68+
69+ def load (file_name : str , validate : bool = False ) -> dict :
3670 """Load ADX file to dictionary
3771 The XML is validated against the generic XSD
3872
3973 :param file_name: the file name where the ADX data is stored
74+ :param validate: validate the ADX against the genereic XSD (very slow)
4075 :return: the ADX as a dict
4176 """
4277
43- try :
44- data_dict = ADX_IMPORT_SCHEMA .to_dict (file_name , decimal_type = str )
45-
46- # Flatten records
47- records = []
48- for rec in data_dict ['RECORDS' ]['RECORD' ]:
49- for elem in rec :
50- if type (rec [elem ][0 ]) is str : # Only for str to save APP data
51- rec [elem ] = rec [elem ][0 ]
52- records .append (rec )
53- data_dict ['RECORDS' ] = records
54-
55- # Flatten header
56- header = {}
57- for elem in data_dict ['HEADER' ]:
58- if type (data_dict ['HEADER' ][elem ][0 ]) is str : # Only for str to save USERDEF
59- header [elem ] = data_dict ['HEADER' ][elem ][0 ]
60- data_dict ['HEADER' ] = header
61- except ParseError as exc :
62- raise XmlSyntaxError (str (exc )) from None
63- except xmlschema .validators .exceptions .XMLSchemaChildrenValidationError as exc :
64- raise UndefinedElementException (f'in { exc .elem .tag } ' ) from None
65- except xmlschema .validators .exceptions .XMLSchemaValidationError as exc :
66- raise MalformedValueException (f'Field "{ exc .elem .tag } ": { exc .reason } ' ) from None
78+ with open (file_name , encoding = 'utf-8' ) as xf :
79+ adx_data = xf .read ()
6780
68- return data_dict
81+ return loads ( adx_data , validate )
6982
7083
7184def dump (file_name : str , data_dict : dict ):
@@ -106,5 +119,5 @@ def dump(file_name: str, data_dict: dict):
106119 raise MalformedValueException (f'Field "{ exc .elem .tag } ": { exc .reason } ' ) from None
107120
108121
109- __all__ = ['load' , 'dump' , 'MissingRecordsException' , 'UndefinedElementException' ,
122+ __all__ = ['load' , 'loads' , ' dump' , 'MissingRecordsException' , 'UndefinedElementException' ,
110123 'MalformedValueException' , 'XmlSyntaxError' ]
0 commit comments