def __call__(self): parent = self.xmltreefile().find(self.parent_xpath) if parent is None: raise xcepts.LibvirtXMLNotFoundError("Parent element %s not " "found" % self.parent_xpath) # Don't delete while traversing list todel = [] index = 0 for child in parent.getchildren(): try: # To support an optional text parameter, compatible # with no text parameter. item = self.marshal_to(child.tag, dict(child.items()), index, self.libvirtxml, child.text) except TypeError: item = self.marshal_to(child.tag, dict(child.items()), index, self.libvirtxml) # Always use absolute index (even if item was None) index += 1 # Account for case where child elements are mixed in # with other elements not supported by this class. # Also permits marshal functions to do element filtering # if the class should only address specificly attributed # elements. if item is not None: todel.append(child) for child in todel: parent.remove(child)
def element_by_parent(self, parent_xpath, tag_name, create=True): """ Retrieve/create an element instance at parent_xpath/tag_name """ type_check('parent_xpath', parent_xpath, str) type_check('tag_name', tag_name, str) parent_element = self.xmltreefile().find(parent_xpath) if (parent_element == self.xmltreefile().getroot() and parent_element.tag == tag_name): return parent_element excpt_str = ('Exception thrown from %s for property "%s" while' ' looking for element tag "%s", on parent at xpath' ' "%s", in XML\n%s\n' % (self.operation, self.property_name, tag_name, parent_xpath, str(self.xmltreefile()))) if parent_element is None: raise xcepts.LibvirtXMLAccessorError(excpt_str) try: element = parent_element.find(tag_name) except: logging.error(excpt_str) raise if element is None: if create: # Create the element element = xml_utils.ElementTree.SubElement( parent_element, tag_name) else: # create == False raise xcepts.LibvirtXMLNotFoundError( 'Error in %s for property ' '"%s", element tag "%s" not ' 'found on parent at xpath "%s"' ' in XML\n%s\n' % (self.operation, self.property_name, tag_name, parent_xpath, str(self.xmltreefile()))) return element
def __call__(self): element = self.element_by_parent(self.parent_xpath, self.tag_name, create=False) value = element.get(self.attribute, None) if value is None: raise xcepts.LibvirtXMLNotFoundError( "Attribute %s not found " "on element %s" % (self.attribute, element.tag)) return value
def get_section_string(self, xpath): """ Returns the content of section in xml. """ section = self.xmltreefile.find(xpath) if section is None: raise xcepts.LibvirtXMLNotFoundError("Path %s is not found." % xpath) return self.xmltreefile.get_element_string(xpath)
def element_by_parent(self, parent_xpath, tag_name, create=True, nested=False): """ Retrieve/create an element instance at parent_xpath/tag_name :param parent_xpath: xpath of parent element :param tag_name: name of element under parent to retrieve/create :param create: True to create new element if not exist :param nested: True if target element is supposed to be sub-element :return: ElementTree.Element instance :raise: LibvirtXMLError: If element not exist & create=False """ type_check('parent_xpath', parent_xpath, str) type_check('tag_name', tag_name, str) parent_element = self.xmltreefile().find(parent_xpath) if (parent_element == self.xmltreefile().getroot() and parent_element.tag == tag_name) and nested is False: return parent_element excpt_str = ('Exception thrown from %s for property "%s" while' ' looking for element tag "%s", on parent at xpath' ' "%s", in XML\n%s\n' % (self.operation, self.property_name, tag_name, parent_xpath, str(self.xmltreefile()))) if parent_element is None: if create: # This will only work for simple XPath strings self.xmltreefile().create_by_xpath(parent_xpath) parent_element = self.xmltreefile().find(parent_xpath) # if create or not, raise if not exist if parent_element is None: raise xcepts.LibvirtXMLAccessorError(excpt_str) try: element = parent_element.find(tag_name) except Exception: logging.error(excpt_str) raise if element is None: if create: # Create the element element = xml_utils.ElementTree.SubElement( parent_element, tag_name) else: # create is False raise xcepts.LibvirtXMLNotFoundError( 'Error in %s for property ' '"%s", element tag "%s" not ' 'found on parent at xpath "%s"' ' in XML\n%s\n' % (self.operation, self.property_name, tag_name, parent_xpath, str(self.xmltreefile()))) return element
def __call__(self, value): type_check('value', value, list) # Allow other classes to generate parent structure parent = self.xmltreefile().find(self.parent_xpath) if parent is None: # Create parent xpath if not exists self.xmltreefile().create_by_xpath(self.parent_xpath) parent = self.xmltreefile().find(self.parent_xpath) if parent is None: raise xcepts.LibvirtXMLNotFoundError( 'Parent xpath %s not found.' % self.parent_xpath) # Remove existing by calling accessor method, allowing # any "untouchable" or "filtered" elements (by marshal) # to be ignored and left as-is. delattr(self.libvirtxml, self.property_name) # Allow user-defined marshal function to determine # if item order is important. Also give more meaningful # exception message below, if there is a problem. index = 0 for item in value: try: # Call user-defined conversion from simple # format, back to Element instances. element_tuple = self.marshal_from(item, index, self.libvirtxml) except ValueError: # Defined in marshal API, to help with error reporting # and debugging with more rich message. msg = ("Call to %s by set accessor method for property %s " "with unsupported item type %s, at index %d, " " with value %s." % (str(self.marshal_from), self.property_name, str(type(item)), index, str(item))) raise xcepts.LibvirtXMLAccessorError(msg) # Handle xml sub-element items if self.has_subclass: parent.append(element_tuple[1].xmltreefile.getroot()) self.xmltreefile().write() continue # Handle element text values in element_tuple[1]. text = None new_dict = element_tuple[1].copy() if 'text' in list(element_tuple[1].keys()): del new_dict['text'] # To support text in element, marshal_from may return an # additional text value, check the length of element tuple if len(element_tuple) == 3: text = element_tuple[2] parent_element = xml_utils.ElementTree.SubElement( parent, element_tuple[0], new_dict, text) # To support child element contains text, create sub element # with text under new created parent element. if 'text' in list(element_tuple[1].keys()): text_dict = element_tuple[1]['text'] attr_dict = {} for text_key, text_val in list(text_dict.items()): xml_utils.ElementTree.SubElement( parent_element, text_key, attr_dict, text_val) index += 1 self.xmltreefile().write()