Exemple #1
0
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)
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
    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
Exemple #10
0
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
Exemple #11
0
    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