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
def _update_dates(self, xpath_root=None, **update_props): """ Default update operation for Dates metadata :see: gis_metadata.utils._complex_definitions[DATES] """ tree_to_update = update_props['tree_to_update'] prop = update_props['prop'] values = (update_props['values'] or {}).get(DATE_VALUES) or u'' xpaths = self._data_structures[prop] if not self.dates: date_xpaths = xpath_root elif self.dates[DATE_TYPE] != DATE_TYPE_RANGE: date_xpaths = xpaths.get(self.dates[DATE_TYPE], u'') else: date_xpaths = [ xpaths[DATE_TYPE_RANGE_BEGIN], xpaths[DATE_TYPE_RANGE_END] ] if xpath_root: remove_element(tree_to_update, xpath_root) return update_property(tree_to_update, xpath_root, date_xpaths, prop, values)
def _get_template(self, root=None, **metadata_defaults): """ Iterate over items metadata_defaults {prop: val, ...} to populate template """ if root is None: if self._data_map is None: self._init_data_map() root = self._xml_root = self._data_map['_root'] template_tree = self._xml_tree = create_element_tree(root) for prop, val in iteritems(metadata_defaults): path = self._data_map.get(prop) if path and val: setattr(self, prop, val) update_property(template_tree, None, path, prop, val) return template_tree
def update(self, use_template=False, **metadata_defaults): """ Validates instance properties and updates either a template or the original XML tree with them. :param use_template: if True, updates a new template XML tree; otherwise the original XML tree """ self.validate() tree_to_update = self._xml_tree if not use_template else self._get_template( **metadata_defaults) supported_props = self._metadata_props for prop, xpath in iteritems(self._data_map): if not prop.startswith('_') or prop.strip('_') in supported_props: # Send only public or alternate properties update_property(tree_to_update, self._get_xroot_for(prop), xpath, prop, getattr(self, prop, u''), supported_props) return tree_to_update
def update(self, use_template=False, **metadata_defaults): """ OVERRIDDEN: Prevents writing multiple CharacterStrings per XPATH property """ self.validate() tree_to_update = self._xml_tree if not use_template else self._get_template(**metadata_defaults) supported_props = self._metadata_props # Iterate over keys, and extract non-primitive root for all XPATHs # xroot = identificationInfo/MD_DataIdentification/abstract/ # xpath = identificationInfo/MD_DataIdentification/abstract/CharacterString # # This prevents multiple primitive tags from being inserted under an element for prop, xpath in iteritems(self._data_map): if not prop.startswith('_') or prop.strip('_') in supported_props: # Send only public or alternate properties xroot = self._trim_xpath(xpath, prop) values = getattr(self, prop, u'') update_property(tree_to_update, xroot, xpath, prop, values, supported_props) return tree_to_update
def _update_raster_info(self, **update_props): """ Derives multiple dimensions from a single raster_info complex struct """ tree_to_update = update_props['tree_to_update'] prop = update_props['prop'] values = update_props.pop('values') # Update number of dimensions at raster_info root (applies to all dimensions below) xroot, xpath = None, self._data_map['_ri_num_dims'] raster_info = [ update_property(tree_to_update, xroot, xpath, prop, values.get('dimensions', u'')) ] # Derive vertical, longitude, and latitude dimensions from raster_info xpath_root = self._get_xroot_for(prop) xpath_map = self._data_structures[prop] v_dimension = {} if values.get('vertical_count'): v_dimension = v_dimension.fromkeys(xpath_map, u'') v_dimension['type'] = 'vertical' v_dimension['size'] = values.get('vertical_count', u'') x_dimension = {} if values.get('column_count') or values.get('x_resolution'): x_dimension = x_dimension.fromkeys(xpath_map, u'') x_dimension['type'] = 'column' x_dimension['size'] = values.get('column_count', u'') x_dimension['value'] = values.get('x_resolution', u'') y_dimension = {} if values.get('row_count') or values.get('y_resolution'): y_dimension = y_dimension.fromkeys(xpath_map, u'') y_dimension['type'] = 'row' y_dimension['size'] = values.get('row_count', u'') y_dimension['value'] = values.get('y_resolution', u'') # Update derived dimensions as complex list, and append affected elements for return update_props['prop'] = RASTER_DIMS update_props['values'] = [v_dimension, x_dimension, y_dimension] raster_info += update_complex_list(xpath_root=xpath_root, xpath_map=xpath_map, **update_props) return raster_info