[Erp5-report] r30048 - in /erp5/trunk/utils/erp5diff: ERP5Diff.py README
nobody at svn.erp5.org
nobody at svn.erp5.org
Tue Oct 27 18:32:14 CET 2009
Author: nicolas
Date: Tue Oct 27 18:32:11 2009
New Revision: 30048
URL: http://svn.erp5.org?rev=30048&view=rev
Log:
- Change output of xupdate:append by adding Implied attribute child
- Calculate position of node regarding his parent not by counting his position in child_list
- All equals nodes (c14n) are not compared anymore
- Fix last tested bugs
Modified:
erp5/trunk/utils/erp5diff/ERP5Diff.py
erp5/trunk/utils/erp5diff/README
Modified: erp5/trunk/utils/erp5diff/ERP5Diff.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5diff/ERP5Diff.py?rev=30048&r1=30047&r2=30048&view=diff
==============================================================================
--- erp5/trunk/utils/erp5diff/ERP5Diff.py [utf8] (original)
+++ erp5/trunk/utils/erp5diff/ERP5Diff.py [utf8] Tue Oct 27 18:32:11 2009
@@ -52,7 +52,7 @@
# Declarative interfaces
zope.interface.implements(IERP5Diff,)
- __version__ = 0.3
+ __version__ = 0.4
def __init__(self):
"""
@@ -177,53 +177,52 @@
remove_element.attrib['select'] = path
root.append(remove_element)
- def _xupdateInsertBefore(self, element_list, path):
- """
- Insert elements before the element at 'path'.
- """
- root = self._getResultRoot()
- insert_element = etree.Element('{%s}insert-before' % self._ns, nsmap=root.nsmap)
- insert_element.attrib['select'] = path
+ def _xupdateAppendElements(self, element_list, path):
+ """
+ Append elements to the element at 'path'.
+ xupdate:append
+ xupdate:insert-before
+ """
+ root = self._getResultRoot()
+ if not element_list:
+ return
+ parent_element = element_list[0].getparent()
+ len_total_child_list = len(parent_element)
+ last_element = None
for element in element_list:
- child_element = etree.Element('{%s}element' % self._ns, nsmap=root.nsmap)
+ if parent_element.index(element) == 0:
+ append_element = etree.SubElement(root, '{%s}append' % self._ns, nsmap=root.nsmap)
+ append_element.attrib.update({'select': path,
+ 'child': 'first()'})
+ elif parent_element.index(element) == (len_total_child_list -1):
+ append_element = etree.SubElement(root, '{%s}append' % self._ns, nsmap=root.nsmap)
+ append_element.attrib.update({'select': path,
+ 'child': 'last()'})
+ elif element.getprevious() in element_list:
+ #reuse same container as preceding
+ append_element = last_append_element
+ elif element.getnext() not in element_list:
+ append_element = etree.SubElement(root, '{%s}insert-before' % self._ns, nsmap=root.nsmap)
+ path_list = self._makeRelativePathList([element.getnext()])
+ next_sibling_path = self._concatPath(path, path_list[0])
+ append_element.attrib['select'] = next_sibling_path
+ else:
+ raise NotImplementedError
+ child_element = etree.SubElement(append_element, '{%s}element' % self._ns, nsmap=root.nsmap)
child_element.attrib['name'] = element.tag
attr_map = element.attrib
for name, value in attr_map.items():
- attr_element = etree.Element('{%s}attribute' % self._ns, nsmap=root.nsmap)
+ attr_element = etree.SubElement(child_element, '{%s}attribute' % self._ns, nsmap=root.nsmap)
attr_element.attrib['name'] = name
attr_element.text = value
- child_element.append(attr_element)
for child in element:
clone_node = deepcopy(child)
child_element.append(clone_node)
if self._hasChildren(child_element):
child_element[-1].tail = element.text
- insert_element.append(child_element)
- root.append(insert_element)
-
- def _xupdateAppendElements(self, element_list, path):
- """
- Append elements to the element at 'path'.
- """
- root = self._getResultRoot()
- append_element = etree.Element('{%s}append' % self._ns, nsmap=root.nsmap)
- append_element.attrib['select'] = path
- for element in element_list:
- child_element = etree.Element('{%s}element' % self._ns, nsmap=root.nsmap)
- child_element.attrib['name'] = element.tag
- attr_map = element.attrib
- for name, value in attr_map.items():
- attr_element = etree.Element('{%s}attribute' % self._ns, nsmap=root.nsmap)
- attr_element.attrib['name'] = name
- attr_element.text = value
- child_element.append(attr_element)
- for child in element:
- clone_node = deepcopy(child)
- child_element.append(clone_node)
- if self._hasChildren(child_element):
- child_element[-1].tail = element.text
- append_element.append(child_element)
- root.append(append_element)
+ else:
+ child_element.text = element.text
+ last_append_element = append_element
def _testElements(self, element1, element2):
"""
@@ -304,14 +303,6 @@
"""
Make a list of relative paths from a list of elements.
"""
- num_map = {}
- count_map = {}
- for element in element_list:
- if element.tag in num_map:
- num_map[element.tag] += 1
- else:
- num_map[element.tag] = 1
- count_map[element.tag] = 1
path_list = []
for element in element_list:
@@ -328,17 +319,18 @@
position_predicate = ''
len_all_similar_sibling = len(element.xpath('../*[@id = "%s"]' % id_val))
if len_all_similar_sibling > 1:
- position = len_all_similar_sibling - element.xpath('count(following-sibling::%s[@id = "%s"])' % (element.tag, id_val) )
+ position = len_all_similar_sibling - element.xpath('count(following-sibling::%s[@id = "%s"])' % (element.tag, id_val))
position_predicate = '[%i]' % position
path_list.append("%s[@id='%s']%s" % (element.tag, id_val, position_predicate,))
# Increase the count, for a case where other elements with the same tag name do not have
# 'id' attrib.
- count_map[element.tag] += 1
- elif num_map[element.tag] > 1:
- path_list.append('%s[%d]' % (element.tag, count_map[element.tag]))
- count_map[element.tag] += 1
- else:
- path_list.append(element.tag)
+ else:
+ len_all_similar_sibling = len(element.findall('../%s' % element.tag))
+ if len_all_similar_sibling > 1:
+ position = len_all_similar_sibling - len(list(element.itersiblings(tag=element.tag)))
+ path_list.append('%s[%d]' % (element.tag, position))
+ else:
+ path_list.append(element.tag)
return path_list
@@ -363,6 +355,33 @@
if type(child) == etree._Element:
text += child.text
return text
+
+ def _removeStrictEqualsSubNodeList(self, old_list, new_list):
+ """Remove inside list all elements which are similar
+ by using c14n serialisation
+ """
+ old_candidate_list = old_list[:]
+ new_candidate_list = new_list[:]
+ for old_element in old_list:
+ old_tree = etree.fromstring(etree.tostring(old_element)).getroottree()
+ f = StringIO()
+ old_tree.write_c14n(f)
+ old_C14n = f.getvalue()
+ for new_element in new_list:
+ if new_element not in new_candidate_list:
+ continue
+ new_tree = etree.fromstring(etree.tostring(new_element)).getroottree()
+ f = StringIO()
+ new_tree.write_c14n(f)
+ new_C14n = f.getvalue()
+ if old_C14n == new_C14n:
+ if new_element in new_candidate_list:
+ new_candidate_list.remove(new_element)
+ if old_element in old_candidate_list:
+ old_candidate_list.remove(old_element)
+ break
+ return old_candidate_list, new_candidate_list
+
def _compareChildNodes(self, old_element, new_element, path):
"""
@@ -404,8 +423,9 @@
# The contents are elements.
self._p("Both have elements.")
old_list = self._aggregateElements(old_element)
+ new_list = self._aggregateElements(new_element)
+ old_list, new_list = self._removeStrictEqualsSubNodeList(old_list, new_list)
path_list = self._makeRelativePathList(old_list)
- new_list = self._aggregateElements(new_element)
new_start = 0
new_len = len(new_list)
for old_node, node_path in zip(old_list, path_list):
@@ -415,9 +435,6 @@
if self._testElements(old_node, new_node):
self._testAttributes(old_node, new_node, child_path)
self._compareChildNodes(old_node, new_node, child_path)
- if new_current > new_start:
- # There are skipped nodes in the new children.
- self._xupdateInsertBefore(new_list[new_start:new_current], child_path)
new_start = new_current + 1
break
else:
Modified: erp5/trunk/utils/erp5diff/README
URL: http://svn.erp5.org/erp5/trunk/utils/erp5diff/README?rev=30048&r1=30047&r2=30048&view=diff
==============================================================================
--- erp5/trunk/utils/erp5diff/README [utf8] (original)
+++ erp5/trunk/utils/erp5diff/README [utf8] Tue Oct 27 18:32:11 2009
@@ -219,6 +219,8 @@
... <object portal_type="Person" id="313731">
... <local_role type="tokens" id="tk"><?xml version="1.0"?><marshal><tuple><string>Manager</string><string>Owner</string></tuple></marshal></local_role>
... <local_permission type="tokens" id="Access contents information"><?xml version="1.0"?></local_permission>
+ ... <local_permission type="tokens" id="Add portal content"><?xml version="1.0"?></local_permission>
+ ... <local_permission type="tokens" id="View"><?xml version="1.0"?></local_permission>
... </object>
... </erp5>
... """
@@ -226,7 +228,11 @@
... <erp5>
... <object portal_type="Person" id="313731">
... <local_role type="tokens" id="tatuya"><?xml version="1.0"?><marshal><tuple><string>Owner</string></tuple></marshal></local_role>
+ ... <JohnDoe>Go to the beach</JohnDoe>
... <local_permission type="tokens" id="Access contents information"><?xml version="1.0"?></local_permission>
+ ... <local_permission type="tokens" id="Add portal content"><?xml version="1.0"?></local_permission>
+ ... <local_permission type="tokens" id="Manage portal content"><?xml version="1.0"?></local_permission>
+ ... <local_permission type="tokens" id="View"><?xml version="1.0"?></local_permission>
... </object>
... </erp5>
... """
@@ -234,8 +240,12 @@
>>> erp5diff.output()
<xupdate:modifications xmlns:xupdate="http://www.xmldb.org/xupdate" version="1.0">
<xupdate:remove select="/object[@id='313731']/local_role[@id='tk']"/>
- <xupdate:insert-before select="/object[@id='313731']/local_permission[@id='Access contents information']">
- <xupdate:element name="local_role"><xupdate:attribute name="type">tokens</xupdate:attribute><xupdate:attribute name="id">tatuya</xupdate:attribute><?xml version="1.0"?><marshal><tuple><string>Owner</string></tuple></marshal></xupdate:element>
+ <xupdate:append select="/object[@id='313731']" child="first()">
+ <xupdate:element name="local_role"><xupdate:attribute name="type">tokens</xupdate:attribute><xupdate:attribute name="id">tatuya</xupdate:attribute><?xml version="1.0"?><marshal><tuple><string>Owner</string></tuple></marshal></xupdate:element>
+ <xupdate:element name="JohnDoe">Go to the beach</xupdate:element>
+ </xupdate:append>
+ <xupdate:insert-before select="/object[@id='313731']/local_permission[@id='View']">
+ <xupdate:element name="local_permission"><xupdate:attribute name="type">tokens</xupdate:attribute><xupdate:attribute name="id">Manage portal content</xupdate:attribute><?xml version="1.0"?></xupdate:element>
</xupdate:insert-before>
</xupdate:modifications>
@@ -284,8 +294,10 @@
<xupdate:modifications xmlns:xupdate="http://www.xmldb.org/xupdate" version="1.0">
<xupdate:remove select="/object[@id='313730']/first_name"/>
<xupdate:remove select="/object[@id='313730']/last_name"/>
- <xupdate:append select="/object[@id='313730']">
+ <xupdate:append select="/object[@id='313730']" child="first()">
<xupdate:element name="given_name"><xupdate:attribute name="type">string</xupdate:attribute>Tatuya</xupdate:element>
+ </xupdate:append>
+ <xupdate:append select="/object[@id='313730']" child="last()">
<xupdate:element name="family_name"><xupdate:attribute name="type">string</xupdate:attribute>Kamada</xupdate:element>
</xupdate:append>
</xupdate:modifications>
@@ -589,9 +601,9 @@
>>> erp5diff.compare(old_xml, new_xml)
>>> erp5diff.output()
<xupdate:modifications xmlns:xupdate="http://www.xmldb.org/xupdate" version="1.0">
- <xupdate:remove select="/object[@id='313730']/workflow_action[2]"/>
- <xupdate:remove select="/object[@id='313730']/workflow_action[3]"/>
- <xupdate:remove select="/object[@id='313730']/workflow_action[4]"/>
+ <xupdate:remove select="/object[@id='313730']/workflow_action[@id='edit_workflow'][2]"/>
+ <xupdate:remove select="/object[@id='313730']/workflow_action[@id='edit_workflow'][3]"/>
+ <xupdate:remove select="/object[@id='313730']/workflow_action[@id='edit_workflow'][4]"/>
</xupdate:modifications>
21. Modify two elements that have same id
More information about the Erp5-report
mailing list