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: raise xcepts.LibvirtXMLNotFoundError # 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) xml_utils.ElementTree.SubElement(parent, element_tuple[0], element_tuple[1]) index += 1 self.xmltreefile().write()
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, value): type_check('value', value, list) # Allow other classes to generate parent structure parent = self.xmltreefile().find(self.parent_xpath) if parent is None: raise xcepts.LibvirtXMLNotFoundError # 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 element text values in element_tuple[1]. text = None new_dict = element_tuple[1].copy() if 'text' in 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 element_tuple[1].keys(): text_dict = element_tuple[1]['text'] attr_dict = {} for text_key, text_val in text_dict.items(): xml_utils.ElementTree.SubElement( parent_element, text_key, attr_dict, text_val) index += 1 self.xmltreefile().write()
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