def _update_keywords(self, **update_props):
        """ Update operation for ISO type-specific Keywords metadata: Theme or Place """

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = update_props['values']

        keywords = []

        if prop in [KEYWORDS_PLACE, KEYWORDS_THEME]:
            xpath_root = self._data_map['_keywords_root']
            xpath_map = self._data_structures[update_props['prop']]

            xtype = xpath_map['keyword_type']
            xroot = xpath_map['keyword_root']
            xpath = xpath_map['keyword']

            if prop == KEYWORDS_PLACE:
                ktype = KEYWORD_TYPE_PLACE
            elif prop == KEYWORDS_THEME:
                ktype = KEYWORD_TYPE_THEME

            # Remove descriptiveKeyword nodes according to type
            for element in get_elements(tree_to_update, xpath_root):
                if get_element_text(element, xtype).lower() == ktype.lower():
                    remove_element(tree_to_update, xpath_root)

            element = insert_element(tree_to_update, 0, xpath_root)
            insert_element(element, 0, xtype, ktype)  # Add the type node

            keywords.extend(update_property(element, xroot, xpath, prop, values))

        return keywords
    def _update_keywords(self, **update_props):
        """ Update operation for ISO type-specific Keywords metadata: Theme or Place """

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = update_props['values']

        keywords = []

        if prop in KEYWORD_PROPS:
            xpath_root = self._data_map['_keywords_root']
            xpath_map = self._data_structures[prop]

            xtype = xpath_map['keyword_type']
            xroot = xpath_map['keyword_root']
            xpath = xpath_map['keyword']
            ktype = KEYWORD_TYPES[prop]

            # Remove descriptiveKeyword nodes according to type
            for element in get_elements(tree_to_update, xpath_root):
                if get_element_text(element, xtype).lower() == ktype.lower():
                    remove_element(tree_to_update, xpath_root)

            element = insert_element(tree_to_update, 0, xpath_root)
            insert_element(element, 0, xtype, ktype)  # Add the type node

            keywords.extend(update_property(element, xroot, xpath, prop, values))

        return keywords
Esempio n. 3
0
    def update_element(elem, idx, root, path, vals):
        """ Internal helper function to encapsulate single item update """

        has_root = bool(root and len(path) > len(root) and path.startswith(root))
        path, attr = get_xpath_tuple(path)  # 'path/@attr' to ('path', 'attr')

        if attr:
            removed = [get_element(elem, path)]
            remove_element_attributes(removed[0], attr)
        elif not has_root:
            removed = wrap_value(remove_element(elem, path))
        else:
            path = get_xpath_branch(root, path)
            removed = [] if idx != 0 else [remove_element(e, path, True) for e in get_elements(elem, root)]

        if not vals:
            return removed

        items = []

        for i, val in enumerate(wrap_value(vals)):
            elem_to_update = elem

            if has_root:
                elem_to_update = insert_element(elem, (i + idx), root)

            val = val.decode('utf-8') if not isinstance(val, string_types) else val
            if not attr:
                items.append(insert_element(elem_to_update, i, path, val))
            else:
                items.append(insert_element(elem_to_update, i, path, **{attr: val}))

        return items
Esempio n. 4
0
    def test_arcgis_parser(self):
        """ Tests behavior unique to the FGDC parser """

        # Test dates structure defaults

        # Remove multiple dates to ensure range is queried
        arcgis_element = get_remote_element(self.arcgis_file)
        remove_element(arcgis_element, "dataIdInfo/dataExt/tempEle/TempExtent/exTemp/TM_Instant", True)

        # Assert that the backup dates are read in successfully
        arcgis_parser = ArcGISParser(element_to_string(arcgis_element))
        self.assertEqual(arcgis_parser.dates, {"type": "range", "values": ["Date Range Start", "Date Range End"]})

        # Remove one of the date range values and assert that only the end date is read in as a single
        remove_element(arcgis_element, "dataIdInfo/dataExt/tempEle/TempExtent/exTemp/TM_Period/tmBegin", True)
        arcgis_parser = ArcGISParser(element_to_string(arcgis_element))
        self.assertEqual(arcgis_parser.dates, {"type": "single", "values": ["Date Range End"]})

        # Remove the last of the date range values and assert that no dates are read in
        remove_element(arcgis_element, "dataIdInfo/dataExt/tempEle/TempExtent/exTemp/TM_Period", True)
        arcgis_parser = ArcGISParser(element_to_string(arcgis_element))
        self.assertEqual(arcgis_parser.dates, {})

        # Insert a single date value and assert that only it is read in

        single_path = "dataIdInfo/dataExt/tempEle/TempExtent/exTemp/TM_Instant/tmPosition"
        single_text = "Single Date"
        insert_element(arcgis_element, 0, single_path, single_text)

        arcgis_parser = ArcGISParser(element_to_string(arcgis_element))
        self.assertEqual(arcgis_parser.dates, {"type": "single", "values": [single_text]})
Esempio n. 5
0
    def _update_report_item(self, **update_props):
        """ Update the text for each element at the configured path if attribute matches """

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = wrap_value(update_props['values'])
        xroot = self._get_xroot_for(prop)

        attr_key = 'type'
        attr_val = u''

        if prop == 'attribute_accuracy':
            attr_val = 'DQQuanAttAcc'
        elif prop == 'dataset_completeness':
            attr_val = 'DQCompOm'

        # Clear (make empty) all elements of the appropriate type
        for elem in get_elements(tree_to_update, xroot):
            if get_element_attributes(elem).get(attr_key) == attr_val:
                clear_element(elem)

        # Remove all empty elements, including those previously cleared
        remove_empty_element(tree_to_update, xroot)

        # Insert elements with correct attributes for each new value

        attrs = {attr_key: attr_val}
        updated = []

        for idx, value in enumerate(values):
            elem = insert_element(tree_to_update, idx, xroot, **attrs)
            updated.append(insert_element(elem, idx, 'measDesc', value))

        return updated
    def _update_report_item(self, **update_props):
        """ Update the text for each element at the configured path if attribute matches """

        tree_to_update = update_props['tree_to_update']
        prop = update_props['prop']
        values = wrap_value(update_props['values'])
        xroot = self._get_xroot_for(prop)

        attr_key = 'type'
        attr_val = u''

        if prop == 'attribute_accuracy':
            attr_val = 'DQQuanAttAcc'
        elif prop == 'dataset_completeness':
            attr_val = 'DQCompOm'

        # Clear (make empty) all elements of the appropriate type
        for elem in get_elements(tree_to_update, xroot):
            if get_element_attributes(elem).get(attr_key) == attr_val:
                clear_element(elem)

        # Remove all empty elements, including those previously cleared
        remove_empty_element(tree_to_update, xroot)

        # Insert elements with correct attributes for each new value

        attrs = {attr_key: attr_val}
        updated = []

        for idx, value in enumerate(values):
            elem = insert_element(tree_to_update, idx, xroot, **attrs)
            updated.append(insert_element(elem, idx, 'measDesc', value))

        return updated
Esempio n. 7
0
def update_complex_list(tree_to_update, xpath_root, xpath_map, prop, values):
    """
    Updates and returns the list of updated complex Elements parsed from tree_to_update.
    :param tree_to_update: the XML tree compatible with element_utils to be updated
    :param xpath_root: the XPATH location of each complex Element
    :param xpath_map: a Dictionary of XPATHs corresponding to the complex structure definition
    :param prop: the property identifying the complex structure to be serialized
    :param values: a List containing the updated complex structures as Dictionaries
    """

    complex_list = []

    remove_element(tree_to_update, xpath_root, True)

    if not values:
        # Returns the elements corresponding to property removed from the tree
        complex_list.append(update_property(tree_to_update, xpath_root, xpath_root, prop, values))
    else:
        for idx, complex_struct in enumerate(wrap_value(values)):

            # Insert a new complex element root for each dict in the list
            complex_element = insert_element(tree_to_update, idx, xpath_root)

            for subprop, value in iteritems(complex_struct):
                xpath = get_xpath_branch(xpath_root, xpath_map[subprop])
                value = get_default_for_complex_sub(prop, subprop, value, xpath)
                complex_list.append(update_property(complex_element, None, xpath, subprop, value))

    return complex_list
Esempio n. 8
0
def update_complex_list(tree_to_update, xpath_root, xpath_map, prop, values):
    """
    Updates and returns the list of updated complex Elements parsed from tree_to_update.
    :param tree_to_update: the XML tree compatible with element_utils to be updated
    :param xpath_root: the XPATH location of each complex Element
    :param xpath_map: a Dictionary of XPATHs corresponding to the complex structure definition
    :param prop: the property identifying the complex structure to be serialized
    :param values: a List containing the updated complex structures as Dictionaries
    """

    complex_list = []

    remove_element(tree_to_update, xpath_root, True)

    if not values:
        # Returns the elements corresponding to property removed from the tree
        complex_list.append(
            update_property(tree_to_update, xpath_root, xpath_root, prop,
                            values))
    else:
        for idx, complex_struct in enumerate(wrap_value(values)):

            # Insert a new complex element root for each dict in the list
            complex_element = insert_element(tree_to_update, idx, xpath_root)

            for subprop, value in iteritems(complex_struct):
                xpath = get_xpath_branch(xpath_root, xpath_map[subprop])
                value = get_default_for_complex_sub(prop, subprop, value,
                                                    xpath)
                complex_list.append(
                    update_property(complex_element, None, xpath, subprop,
                                    value))

    return complex_list
Esempio n. 9
0
    def update_element(elem, idx, root, path, vals):
        """ Internal helper function to encapsulate single item update """

        has_root = bool(root and len(path) > len(root)
                        and path.startswith(root))
        path, attr = get_xpath_tuple(path)  # 'path/@attr' to ('path', 'attr')

        if attr:
            removed = [get_element(elem, path)]
            remove_element_attributes(removed[0], attr)
        elif not has_root:
            removed = wrap_value(remove_element(elem, path))
        else:
            path = get_xpath_branch(root, path)
            removed = [] if idx != 0 else [
                remove_element(e, path, True)
                for e in get_elements(elem, root)
            ]

        if not vals:
            return removed

        items = []

        for i, val in enumerate(wrap_value(vals)):
            elem_to_update = elem

            if has_root:
                elem_to_update = insert_element(elem, (i + idx), root)

            val = val.decode('utf-8') if not isinstance(val,
                                                        string_types) else val
            if not attr:
                items.append(insert_element(elem_to_update, i, path, val))
            elif path:
                items.append(
                    insert_element(elem_to_update, i, path, **{attr: val}))
            else:
                set_element_attributes(elem_to_update, **{attr: val})
                items.append(elem_to_update)

        return items