def parse_message(self, elem): f = Footer(**elem.attrib) for locale, label in self._parse(elem)['text']: f.text.append(InternationalString(**{locale: label})) return f
def read_message(self, source): # Root XML element root = etree.parse(source).getroot() # Message class try: cls = MESSAGE[root.tag] except KeyError: msg = 'Unrecognized message root element {!r}'.format(root.tag) raise ParseError(msg) from None # Reset state self._stack = [] self._index = {} self._current = {} # Parse the tree values = self._parse(root) # Instantiate the message object msg = cls() # Store the header header = values.pop('header', None) if header is None and 'errormessage' in values: # An error message msg.header = Header() # Error message attributes resemble footer attributes values['footer'] = Footer(**values.pop('errormessage')) elif len(header) == 2: # Length-2 list includes DFD/DSD reference msg.header, msg.dataflow = header msg.observation_dimension = self._obs_dim else: # No DFD in the header, e.g. for a StructureMessage msg.header = header[0] # Store the footer msg.footer = values.pop('footer', None) # Finalize according to the message type if cls is DataMessage: # Simply store the datasets msg.data.extend(wrap(values.pop('dataset', []))) elif cls is StructureMessage: structures = values.pop('structures') # Populate dictionaries by ID for attr, name in ( ('dataflow', 'dataflows'), ('codelist', 'codelists'), ('constraint', 'constraints'), ('structure', 'datastructures'), ('category_scheme', 'categoryschemes'), ('concept_scheme', 'concepts'), ('organisation_scheme', 'organisationschemes'), ('provisionagreement', 'provisionagreements'), ): for obj in structures.pop(name, []): getattr(msg, attr)[obj.id] = obj # Check, but do not store, Categorisations # Assemble a list of external categoryschemes ext_cs = [] for key, cs in self._index.items(): if key[0] == 'CategoryScheme' and cs.is_external_reference: ext_cs.append(cs) for c in structures.pop('categorisations', []): if not isinstance(c.artefact, DataflowDefinition): continue assert c.artefact in msg.dataflow.values() missing_cs = True for cs in chain(msg.category_scheme.values(), ext_cs): if c.category in cs: missing_cs = False if cs.is_external_reference: # Store the externally-referred CategoryScheme msg.category_scheme[cs.id] = cs break assert not missing_cs assert len(structures) == 0, structures assert len(values) == 0, values return msg