def _create_root(model): """Initialises an empty main xml tree for model.""" assert (model.main_tree is None) assert (model.main_root is None) model.main_root = rqet.Element(ns['content_types'] + 'Types') model.main_tree = rqet.ElementTree(element=model.main_root)
def _create_doc_props(model, add_as_part=True, root=None, originator=None): """Creates a document properties stub node and optionally adds as child of root and/or to parts forest.""" dp = rqet.Element(ns['cp'] + 'coreProperties') dp.text = rqet.null_xml_text created = rqet.SubElement(dp, ns['dcterms'] + 'created') created.set(ns['xsi'] + 'type', ns['dcterms'] + 'W3CDTF') # not sure of namespace here created.text = time.now() if originator is None: try: originator = str(os.getlogin()) except Exception: originator = 'unknown' creator = rqet.SubElement(dp, ns['dc'] + 'creator') creator.text = originator ver = rqet.SubElement(dp, ns['cp'] + 'version') ver.text = '1.0' if root is not None: root.append(dp) if add_as_part: model.add_part('docProps', None, dp) if model.rels_present: (_, rel_tree) = model.rels_forest['_rels/.rels'] core_rel = rqet.SubElement(rel_tree.getroot(), ns['rels'] + 'Relationship') core_rel.set('Id', 'CoreProperties') core_rel.set('Type', ns_url['rels_md'] + 'core-properties') core_rel.set('Target', 'docProps/core.xml') return dp
def _create_hdf5_dataset_ref(hdf5_uuid, object_uuid, group_tail, root, title='Hdf Proxy'): """Creates a pair of nodes referencing an hdf5 dataset (array) and adds to root.""" assert root is not None assert group_tail if group_tail[0] == '/': group_tail = group_tail[1:] if group_tail[-1] == '/': group_tail = group_tail[:-1] hdf5_path = '/RESQML/' + str(object_uuid) + '/' + group_tail path_node = rqet.Element(ns['eml'] + 'PathInHdfFile') path_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string') path_node.text = hdf5_path root.append(path_node) _create_ref_node('HdfProxy', title, hdf5_uuid, content_type='obj_EpcExternalPartReference', root=root) return path_node
def _create_unknown(root=None): """Creates an Unknown node and optionally adds as child of root.""" unknown = rqet.Element(ns['eml'] + 'Unknown') unknown.set(ns['xsi'] + 'type', ns['eml'] + 'DescriptionString') unknown.text = 'Unknown' if root is not None: root.append(unknown) return unknown
def _new_obj_node(flavour, name_space='resqml2', is_top_lvl_obj=True): """Creates a new main object element and sets attributes (does not add children).""" if flavour.startswith('obj_'): flavour = flavour[4:] node = rqet.Element(ns[name_space] + flavour) node.set('schemaVersion', '2.0') node.set('uuid', str(bu.new_uuid())) if is_top_lvl_obj: node.set(ns['xsi'] + 'type', ns[name_space] + 'obj_' + flavour) node.text = rqet.null_xml_text return node
def _create_ref_node(flavour, title, uuid, content_type=None, root=None): """Create a reference node, optionally add to root.""" assert uuid is not None if flavour.startswith('obj_'): flavour = flavour[4:] if not content_type: content_type = 'obj_' + flavour else: if content_type[0].isupper(): content_type = 'obj_' + content_type prefix = ns['eml'] if flavour == 'HdfProxy' else ns['resqml2'] ref_node = rqet.Element(prefix + flavour) ref_node.set(ns['xsi'] + 'type', ns['eml'] + 'DataObjectReference') ref_node.text = rqet.null_xml_text ct_node = rqet.SubElement(ref_node, ns['eml'] + 'ContentType') ct_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string') if 'EpcExternalPartReference' in content_type: ct_node.text = 'application/x-eml+xml;version=2.0;type=' + content_type else: ct_node.text = 'application/x-resqml+xml;version=2.0;type=' + content_type if not title: title = '(title unavailable)' title_node = rqet.SubElement(ref_node, ns['eml'] + 'Title') title_node.set(ns['xsi'] + 'type', ns['eml'] + 'DescriptionString') title_node.text = title uuid_node = rqet.SubElement(ref_node, ns['eml'] + 'UUID') uuid_node.set(ns['xsi'] + 'type', ns['eml'] + 'UuidString') uuid_node.text = str(uuid) if use_version_string: version_str = rqet.SubElement( ref_node, ns['eml'] + 'VersionString') # I'm guessing what this is version_str.set(ns['xsi'] + 'type', ns['eml'] + 'NameString') version_str.text = bu.version_string(uuid) if root is not None: root.append(ref_node) return ref_node
def _create_source(source, root=None): """Create an extra meta data node holding information on the source of the data, optionally add to root.""" emd_node = rqet.Element(ns['resqml2'] + 'ExtraMetadata') emd_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'NameValuePair') emd_node.text = rqet.null_xml_text name_node = rqet.SubElement(emd_node, ns['resqml2'] + 'Name') name_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string') name_node.text = 'source' value_node = rqet.SubElement(emd_node, ns['resqml2'] + 'Value') value_node.set(ns['xsi'] + 'type', ns['xsd'] + 'string') value_node.text = source if root is not None: root.append(emd_node) return emd_node
def _create_citation(root=None, title='', originator=None): """Creates a citation xml node and optionally appends as a child of root.""" if not title: title = '(no title)' citation = rqet.Element(ns['eml'] + 'Citation') citation.set(ns['xsi'] + 'type', ns['eml'] + 'Citation') citation.text = rqet.null_xml_text title_node = rqet.SubElement(citation, ns['eml'] + 'Title') title_node.set(ns['xsi'] + 'type', ns['eml'] + 'DescriptionString') title_node.text = str(title) originator_node = rqet.SubElement(citation, ns['eml'] + 'Originator') if originator is None: try: originator = str(getpass.getuser()) except Exception: originator = 'unknown' originator_node.set(ns['xsi'] + 'type', ns['eml'] + 'NameString') originator_node.text = originator creation_node = rqet.SubElement(citation, ns['eml'] + 'Creation') creation_node.set(ns['xsi'] + 'type', ns['xsd'] + 'dateTime') creation_node.text = time.now() format_node = rqet.SubElement(citation, ns['eml'] + 'Format') format_node.set(ns['xsi'] + 'type', ns['eml'] + 'DescriptionString') if rqet.pretend_to_be_fesapi: format_node.text = '[F2I-CONSULTING:fesapi]' else: format_node.text = citation_format # todo: add optional description field if root is not None: root.append(citation) return citation
def create_time_index(self, time_index, root = None, check_valid_index = True): """Create a time index node, including time series reference, optionally add to root. arguments: time_index (int): non-negative integer index into the time series, identifying the datetime being referenced by the new node root (optional): if present, the newly created time index xml node is added as a child to this node check_valid_index (boolean, default True): if True, an assertion error is raised if the time index is out of range for this time series returns: the newly created time index xml node note: a time index node is typically part of a recurrent property object; it identifies the datetime relevant to the property array (or other data) by indexing into a time series object """ assert self.uuid is not None if check_valid_index: assert 0 <= time_index < len(self.timestamps), 'time index out of range for time series' t_node = rqet.Element(ns['resqml2'] + 'TimeIndex') t_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'TimeIndex') t_node.text = rqet.null_xml_text index_node = rqet.SubElement(t_node, ns['resqml2'] + 'Index') index_node.set(ns['xsi'] + 'type', ns['xsd'] + 'nonNegativeInteger') index_node.text = str(time_index) self.model.create_time_series_ref(self.uuid, root = t_node) if root is not None: root.append(t_node) return t_node
def _create_patch(p_uuid, ext_uuid=None, root=None, patch_index=0, hdf5_type='DoubleHdf5Array', xsd_type='double', null_value=None, const_value=None, const_count=None, points=False): """Create a node for a patch of values, including ref to hdf5 data set, optionally add to root.""" if const_value is None: assert ext_uuid is not None else: assert const_count is not None and const_count > 0 if hdf5_type.endswith('Hdf5Array'): hdf5_type = hdf5_type[:-9] + 'ConstantArray' lxt = str(xsd_type).lower() discrete = ('int' in lxt) or ('bool' in lxt) if points: assert not discrete patch_node = rqet.Element(ns['resqml2'] + 'PatchOfPoints') patch_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'PatchOfPoints') patch_node.text = rqet.null_xml_text outer_values_tag = 'Points' inner_values_tag = 'Coordinates' hdf_path_tail = 'points_patch' else: patch_node = rqet.Element(ns['resqml2'] + 'PatchOfValues') patch_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'PatchOfValues') patch_node.text = rqet.null_xml_text outer_values_tag = 'Values' inner_values_tag = 'Values' hdf_path_tail = 'values_patch' rep_patch_index = rqet.SubElement( patch_node, ns['resqml2'] + 'RepresentationPatchIndex') rep_patch_index.set(ns['xsi'] + 'type', ns['xsd'] + 'nonNegativeInteger') rep_patch_index.text = str(patch_index) outer_values_node = rqet.SubElement(patch_node, ns['resqml2'] + outer_values_tag) outer_values_node.set(ns['xsi'] + 'type', ns['resqml2'] + hdf5_type) # may also be constant array type outer_values_node.text = rqet.null_xml_text if discrete: if null_value is None: if str(xsd_type).startswith('u'): null_value = 4294967295 # 2^32 - 1, used as default even for 64 bit data! else: null_value = -1 null_value_node = rqet.SubElement(outer_values_node, ns['resqml2'] + 'NullValue') null_value_node.set(ns['xsi'] + 'type', ns['xsd'] + xsd_type) null_value_node.text = str(null_value) if const_value is None: inner_values_node = rqet.SubElement(outer_values_node, ns['resqml2'] + inner_values_tag) inner_values_node.set(ns['xsi'] + 'type', ns['eml'] + 'Hdf5Dataset') inner_values_node.text = rqet.null_xml_text _create_hdf5_dataset_ref(ext_uuid, p_uuid, f'{hdf_path_tail}{patch_index}', root=inner_values_node) else: const_value_node = rqet.SubElement(outer_values_node, ns['resqml2'] + 'Value') const_value_node.set(ns['xsi'] + 'type', ns['xsd'] + xsd_type) const_value_node.text = str(const_value) const_count_node = rqet.SubElement(outer_values_node, ns['resqml2'] + 'Count') const_count_node.set(ns['xsi'] + 'type', ns['xsd'] + 'nonNegativeInteger') const_count_node.text = str(const_count) if root is not None: root.append(patch_node) return patch_node
def create_xml(self, parent_node = None): """Generates xml sub-tree for this contact interpretation, for inclusion as element of high level interpretation. arguments: parent_node (lxml.etree._Element, optional): if present, the created sub-tree is added as a child to this node returns: lxml.etree._Element: the root node of the newly created xml sub-tree for the contact interpretation """ bci = rqet.Element(ns['resqml2'] + 'ContactInterpretation') bci.set(ns['xsi'] + 'type', ns['resqml2'] + 'BinaryContactInterpretationPart') bci.text = '' cr_node = rqet.SubElement(bci, ns['resqml2'] + 'ContactRelationship') cr_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ContactRelationship') cr_node.text = self.contact_relationship i_node = rqet.SubElement(bci, ns['resqml2'] + 'Index') i_node.set(ns['xsi'] + 'type', ns['xsi'] + 'nonNegativeInteger') i_node.text = str(self.index) if self.part_of_uuid is not None: self.model.create_ref_node('PartOf', self.model.title(uuid = self.part_of_uuid), self.part_of_uuid, content_type = self.model.type_of_uuid(self.part_of_uuid), root = bci) dor_node = self.model.create_ref_node('DirectObject', self.model.title(uuid = self.direct_object_uuid), self.direct_object_uuid, content_type = self.model.type_of_uuid(self.direct_object_uuid), root = bci) dor_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ContactElementReference') if self.direct_object_contact_side: doq_node = rqet.SubElement(dor_node, ns['resqml2'] + 'Qualifier') doq_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ContactSide') doq_node.text = self.direct_object_contact_side if self.direct_object_contact_mode: dosq_node = rqet.SubElement(dor_node, ns['resqml2'] + 'SecondaryQualifier') dosq_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ContactMode') dosq_node.text = self.direct_object_contact_mode v_node = rqet.SubElement(bci, ns['resqml2'] + 'Verb') v_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ContactVerb') v_node.text = self.verb sr_node = self.model.create_ref_node('Subject', self.model.title(uuid = self.subject_uuid), self.subject_uuid, content_type = self.model.type_of_uuid(self.subject_uuid), root = bci) sr_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ContactElementReference') if self.subject_contact_side: sq_node = rqet.SubElement(sr_node, ns['resqml2'] + 'Qualifier') sq_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ContactSide') sq_node.text = self.subject_contact_side if self.subject_contact_mode: ssq_node = rqet.SubElement(sr_node, ns['resqml2'] + 'SecondaryQualifier') ssq_node.set(ns['xsi'] + 'type', ns['resqml2'] + 'ContactMode') ssq_node.text = self.subject_contact_mode if parent_node is not None: parent_node.append(bci) return bci