def applyDiff(self, original_data, diff): """Use xuproc for computing patched content """ # XXX xuproc does not support passing # etree objetcs diff = etree.tostring(diff) return etree.tostring(xuproc.applyXUpdate(xml_xu_string=diff, xml_doc_string=original_data), encoding='utf-8')
def applyDiff(self, original_data, diff): """Use xuproc for computing patched content """ # XXX xuproc does not support passing # etree objetcs if not isinstance(diff, basestring): diff = etree.tostring(diff) return etree.tostring(xuproc.applyXUpdate(xml_xu_string=diff, xml_doc_string=original_data), encoding='utf-8')
def applyXupdate(self, object=None, xupdate=None, previous_xml=None, **kw): """ Parse the xupdate and then it will call the conduit """ conflict_list = [] if isinstance(xupdate, (str, unicode)): xupdate = etree.XML(xupdate, parser=parser) #LOG("applyXupdate", INFO, etree.tostring(xupdate, pretty_print=True)) xupdate_builded = False xpath_expression_update_dict = {} for subnode in xupdate: selection_name = '' original_xpath_expression = subnode.get('select', '') if not xupdate_builded and\ MARSHALLER_NAMESPACE_URI in subnode.nsmap.values()\ or 'block_data' in original_xpath_expression: # It means that the xpath expression is targetting # marshalled values or data nodes. We need to rebuild the original xml # in its own context in order to retrieve original value # We are insde a loop build the XUpdated tree only once xupdate_builded = True # Find the prefix used by marshaller. for prefix, namespace_uri in subnode.nsmap.iteritems(): if namespace_uri == MARSHALLER_NAMESPACE_URI: break # TODO add support of etree objects for xuproc to avoid # serializing tree into string if not isinstance(previous_xml, str): previous_xml = etree.tostring(previous_xml) xupdated_tree = xuproc.applyXUpdate(xml_xu_string=etree.tostring(xupdate), xml_doc_string=previous_xml) if MARSHALLER_NAMESPACE_URI in subnode.nsmap.values(): xpath_expression = original_xpath_expression get_target_parent = subnode.xpath('name()') in XUPDATE_INSERT_LIST context = self.getContextFromXpath(object, xpath_expression, get_target_parent=get_target_parent) base_xpath_expression = xpath_expression\ [:xpath_expression.index(prefix)-1] xupdated_node_list = xupdated_tree.xpath(base_xpath_expression) if xupdated_node_list: xupdated_node = xupdated_node_list[0] else: ValueError('Wrong xpath expression:%r' % base_xpath_expression) if base_xpath_expression not in xpath_expression_update_dict: xpath_expression_update_dict[base_xpath_expression] = \ dict(xml=xupdated_node, object=context, xpath_expression=base_xpath_expression) elif 'block_data' in original_xpath_expression: """XXX Use Qualified Names for block_data nodes to avoid ambiguity """ xpath_expression = original_xpath_expression get_target_parent = subnode.xpath('name()') in XUPDATE_INSERT_LIST context = self.getContextFromXpath(object, xpath_expression, get_target_parent=get_target_parent) base_xpath_expression = xpath_expression\ [:xpath_expression.index('block_data')-1] xupdated_node_list = xupdated_tree.xpath(base_xpath_expression) if xupdated_node_list: xupdated_node = xupdated_node_list[0] else: ValueError('Wrong xpath expression:%r' % base_xpath_expression) if base_xpath_expression not in xpath_expression_update_dict: xpath_expression_update_dict[base_xpath_expression] = \ dict(xml=xupdated_node, object=context, xpath_expression=base_xpath_expression) elif subnode.xpath('name()') in XUPDATE_INSERT_OR_ADD_LIST: conflict_list += self.addNode(xml=subnode, object=object, previous_xml=previous_xml, **kw)['conflict_list'] elif subnode.xpath('name()') == XUPDATE_DEL: conflict_list += self.deleteNode(xml=subnode, object=object, previous_xml=previous_xml, **kw) elif subnode.xpath('name()') == XUPDATE_UPDATE: conflict_list += self.updateNode(xml=subnode, object=object, previous_xml=previous_xml, **kw) # Now apply collected xupdated_node for update_dict in xpath_expression_update_dict.itervalues(): update_dict.update(kw) conflict_list += self.updateNode(previous_xml=previous_xml, **update_dict) return conflict_list
def applyXupdate(self, object=None, xupdate=None, previous_xml=None, **kw): # pylint: disable=redefined-builtin """ Parse the xupdate and then it will call the conduit """ conflict_list = [] if isinstance(xupdate, (str, unicode)): xupdate = etree.XML(xupdate, parser=parser) #LOG("applyXupdate", INFO, etree.tostring(xupdate, pretty_print=True)) xupdate_builded = False xpath_expression_update_dict = {} for subnode in xupdate: original_xpath_expression = subnode.get('select', '') if not xupdate_builded and \ MARSHALLER_NAMESPACE_URI in subnode.nsmap.values() \ or 'block_data' in original_xpath_expression: # It means that the xpath expression is targetting # marshalled values or data nodes. We need to rebuild the original xml # in its own context in order to retrieve original value # We are insde a loop build the XUpdated tree only once xupdate_builded = True # Find the prefix used by marshaller. for prefix, namespace_uri in subnode.nsmap.iteritems(): if namespace_uri == MARSHALLER_NAMESPACE_URI: break # TODO add support of etree objects for xuproc to avoid # serializing tree into string if not isinstance(previous_xml, str): previous_xml = etree.tostring(previous_xml) xupdated_tree = xuproc.applyXUpdate(xml_xu_string=etree.tostring(xupdate), xml_doc_string=previous_xml) if MARSHALLER_NAMESPACE_URI in subnode.nsmap.values(): xpath_expression = original_xpath_expression get_target_parent = subnode.xpath('name()') in XUPDATE_INSERT_LIST context = self.getContextFromXpath(object, xpath_expression, get_target_parent=get_target_parent) base_xpath_expression = xpath_expression\ [:xpath_expression.index(prefix)-1] xupdated_node_list = xupdated_tree.xpath(base_xpath_expression) if xupdated_node_list: xupdated_node = xupdated_node_list[0] else: ValueError('Wrong xpath expression:%r' % base_xpath_expression) if base_xpath_expression not in xpath_expression_update_dict: xpath_expression_update_dict[base_xpath_expression] = \ dict(xml=xupdated_node, object=context, xpath_expression=base_xpath_expression) elif 'block_data' in original_xpath_expression: """XXX Use Qualified Names for block_data nodes to avoid ambiguity """ xpath_expression = original_xpath_expression get_target_parent = subnode.xpath('name()') in XUPDATE_INSERT_LIST context = self.getContextFromXpath(object, xpath_expression, get_target_parent=get_target_parent) base_xpath_expression = xpath_expression\ [:xpath_expression.index('block_data')-1] xupdated_node_list = xupdated_tree.xpath(base_xpath_expression) if xupdated_node_list: xupdated_node = xupdated_node_list[0] else: ValueError('Wrong xpath expression:%r' % base_xpath_expression) if base_xpath_expression not in xpath_expression_update_dict: xpath_expression_update_dict[base_xpath_expression] = \ dict(xml=xupdated_node, object=context, xpath_expression=base_xpath_expression) elif subnode.xpath('name()') in XUPDATE_INSERT_OR_ADD_LIST: conflict_list += self.addNode(xml=subnode, object=object, previous_xml=previous_xml, **kw)['conflict_list'] elif subnode.xpath('name()') == XUPDATE_DEL: conflict_list += self.deleteNode(xml=subnode, object=object, previous_xml=previous_xml, **kw) elif subnode.xpath('name()') == XUPDATE_UPDATE: conflict_list += self.updateNode(xml=subnode, object=object, previous_xml=previous_xml, **kw) # Now apply collected xupdated_node for update_dict in xpath_expression_update_dict.itervalues(): update_dict.update(kw) conflict_list += self.updateNode(previous_xml=previous_xml, **update_dict) return conflict_list