Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
erp5diff
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
erp5diff
Commits
27a9bcf3
Commit
27a9bcf3
authored
Dec 02, 2009
by
Nicolas Delaby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Declare prefix used in xpath expression
parent
a4b49f23
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
41 additions
and
34 deletions
+41
-34
ERP5Diff.py
ERP5Diff.py
+33
-28
README
README
+8
-6
No files found.
ERP5Diff.py
View file @
27a9bcf3
...
...
@@ -67,7 +67,7 @@ class ERP5Diff:
# Declarative interfaces
zope
.
interface
.
implements
(
IERP5Diff
,)
__version__
=
0.
6
__version__
=
0.
7
def
__init__
(
self
):
"""
...
...
@@ -133,12 +133,15 @@ class ERP5Diff:
index
=
attr_name
.
index
(
'}'
)
local_name
=
attr_name
[
index
+
1
:]
namespace_uri
=
attr_name
[
1
:
index
]
prefix
=
[
t
[
0
]
for
t
in
element
.
nsmap
.
iteritems
()
if
t
[
1
]
==
namespace_uri
][
0
]
if
namespace_uri
==
'http://www.w3.org/XML/1998/namespace'
:
prefix
=
'xml'
else
:
prefix
=
[
t
[
0
]
for
t
in
element
.
nsmap
.
iteritems
()
if
t
[
1
]
==
namespace_uri
][
0
]
return
'%s:%s'
%
(
prefix
,
local_name
,),
namespace_uri
else
:
return
attr_name
,
None
def
_xupdateAppendAttributes
(
self
,
attr_dict
,
path
):
def
_xupdateAppendAttributes
(
self
,
attr_dict
,
path
,
nsmap
=
None
):
"""
Append attrib to the element at 'path'.
"""
...
...
@@ -149,7 +152,7 @@ class ERP5Diff:
key_list
.
sort
()
for
name
in
key_list
:
val
=
attr_dict
[
name
]
attr_element
=
etree
.
Element
(
'{%s}attribute'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
attr_element
=
etree
.
Element
(
'{%s}attribute'
%
self
.
_ns
,
nsmap
=
nsmap
)
name
,
namespace_uri
=
name
attr_element
.
attrib
[
'name'
]
=
name
if
namespace_uri
:
...
...
@@ -158,41 +161,41 @@ class ERP5Diff:
append_element
.
append
(
attr_element
)
root
.
append
(
append_element
)
def
_xupdateRemoveAttribute
(
self
,
name
,
path
):
def
_xupdateRemoveAttribute
(
self
,
name
,
path
,
nsmap
=
None
):
"""
Remove an attribute from the element at 'path'.
"""
root
=
self
.
_getResultRoot
()
remove_element
=
etree
.
Element
(
'{%s}remove'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
remove_element
=
etree
.
Element
(
'{%s}remove'
%
self
.
_ns
,
nsmap
=
nsmap
)
remove_element
.
attrib
[
'select'
]
=
self
.
_concatPath
(
path
,
'attribute::'
+
name
[
0
])
root
.
append
(
remove_element
)
def
_xupdateUpdateAttribute
(
self
,
name
,
val
,
path
):
def
_xupdateUpdateAttribute
(
self
,
name
,
val
,
path
,
nsmap
=
None
):
"""
Update the value of an attribute of the element at 'path'.
"""
root
=
self
.
_getResultRoot
()
update_element
=
etree
.
Element
(
'{%s}update'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
update_element
=
etree
.
Element
(
'{%s}update'
%
self
.
_ns
,
nsmap
=
nsmap
)
update_element
.
attrib
[
'select'
]
=
self
.
_concatPath
(
path
,
'attribute::'
+
name
[
0
])
update_element
.
text
=
val
root
.
append
(
update_element
)
def
_xupdateRenameElement
(
self
,
name
,
path
):
def
_xupdateRenameElement
(
self
,
name
,
path
,
nsmap
=
None
):
"""
Rename an existing element at 'path'.
"""
root
=
self
.
_getResultRoot
()
rename_element
=
etree
.
Element
(
'{%s}rename'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
rename_element
=
etree
.
Element
(
'{%s}rename'
%
self
.
_ns
,
nsmap
=
nsmap
)
rename_element
.
attrib
[
'select'
]
=
path
rename_element
.
text
=
name
root
.
append
(
rename_element
)
def
_xupdateUpdateElement
(
self
,
element
,
path
):
def
_xupdateUpdateElement
(
self
,
element
,
path
,
nsmap
=
None
):
"""
Update the contents of an element at 'path' to that of 'element'.
"""
root
=
self
.
_getResultRoot
()
update_element
=
etree
.
Element
(
'{%s}update'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
update_element
=
etree
.
Element
(
'{%s}update'
%
self
.
_ns
,
nsmap
=
nsmap
)
update_element
.
attrib
[
'select'
]
=
path
if
self
.
_hasChildren
(
element
):
for
child
in
element
:
...
...
@@ -202,16 +205,16 @@ class ERP5Diff:
update_element
.
text
=
element
.
text
root
.
append
(
update_element
)
def
_xupdateRemoveElement
(
self
,
path
):
def
_xupdateRemoveElement
(
self
,
path
,
nsmap
=
None
):
"""
Remove an element at 'path'.
"""
root
=
self
.
_getResultRoot
()
remove_element
=
etree
.
Element
(
'{%s}remove'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
remove_element
=
etree
.
Element
(
'{%s}remove'
%
self
.
_ns
,
nsmap
=
nsmap
)
remove_element
.
attrib
[
'select'
]
=
path
root
.
append
(
remove_element
)
def
_xupdateAppendElements
(
self
,
element_list
,
path
):
def
_xupdateAppendElements
(
self
,
element_list
,
path
,
nsmap
=
None
):
"""
Append elements to the element at 'path'.
xupdate:append
...
...
@@ -227,22 +230,22 @@ class ERP5Diff:
for
element
in
element_list
:
relative_next
=
element
.
getnext
()
relative_previous
=
element
.
getprevious
()
if
element
.
getprevious
()
in
element_list
:
if
relative_previous
in
element_list
:
#reuse same container as preceding
append_element
=
last_append_element
elif
relative_next
is
not
None
and
relative_next
not
in
element_list
:
append_element
=
etree
.
SubElement
(
root
,
'{%s}insert-before'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
append_element
=
etree
.
SubElement
(
root
,
'{%s}insert-before'
%
self
.
_ns
,
nsmap
=
nsmap
)
path_list
=
self
.
_makeRelativePathList
([
relative_next
])
next_sibling_path
=
self
.
_concatPath
(
path
,
path_list
[
0
])
append_element
.
attrib
[
'select'
]
=
next_sibling_path
elif
relative_previous
is
not
None
and
relative_previous
not
in
element_list
:
append_element
=
etree
.
SubElement
(
root
,
'{%s}insert-after'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
append_element
=
etree
.
SubElement
(
root
,
'{%s}insert-after'
%
self
.
_ns
,
nsmap
=
nsmap
)
path_list
=
self
.
_makeRelativePathList
([
relative_previous
])
preceding_sibling_path
=
self
.
_concatPath
(
path
,
path_list
[
0
])
append_element
.
attrib
[
'select'
]
=
preceding_sibling_path
else
:
#xupdate:append by default
append_element
=
etree
.
SubElement
(
root
,
'{%s}append'
%
self
.
_ns
,
nsmap
=
root
.
nsmap
)
append_element
=
etree
.
SubElement
(
root
,
'{%s}append'
%
self
.
_ns
,
nsmap
=
nsmap
)
if
parent_element
.
index
(
element
)
==
0
:
child
=
'first()'
elif
parent_element
.
index
(
element
)
==
(
len_total_child_list
-
1
):
...
...
@@ -258,7 +261,7 @@ class ERP5Diff:
child_element
.
attrib
[
'namespace'
]
=
namespace_uri
attr_map
=
element
.
attrib
for
name
,
value
in
attr_map
.
items
():
attr_element
=
etree
.
SubElement
(
child_element
,
'{%s}attribute'
%
self
.
_ns
,
nsmap
=
roo
t
.
nsmap
)
attr_element
=
etree
.
SubElement
(
child_element
,
'{%s}attribute'
%
self
.
_ns
,
nsmap
=
child_elemen
t
.
nsmap
)
name
,
namespace_uri
=
self
.
_getQName
(
element
,
name
)
attr_element
.
attrib
[
'name'
]
=
name
if
namespace_uri
:
...
...
@@ -318,19 +321,19 @@ class ERP5Diff:
if
name1
in
dict2
:
if
val1
!=
dict2
[
name1
]:
# The value is different.
self
.
_xupdateUpdateAttribute
(
name1
,
dict2
[
name1
],
path
)
self
.
_xupdateUpdateAttribute
(
name1
,
dict2
[
name1
],
path
,
nsmap
=
element
.
nsmap
)
# Mark this attribute.
dict2
[
name1
]
=
None
else
:
# This attribute is removed.
self
.
_xupdateRemoveAttribute
(
name1
,
path
)
self
.
_xupdateRemoveAttribute
(
name1
,
path
,
nsmap
=
element
.
nsmap
)
d
=
{}
for
name2
,
val2
in
dict2
.
iteritems
():
if
val2
is
not
None
:
# This attribute is added.
d
[
name2
]
=
val2
if
d
!=
{}:
self
.
_xupdateAppendAttributes
(
d
,
path
)
self
.
_xupdateAppendAttributes
(
d
,
path
,
nsmap
=
element
.
nsmap
)
def
_checkEmptiness
(
self
,
element
):
"""
...
...
@@ -453,7 +456,7 @@ class ERP5Diff:
elif
old_is_empty
or
new_is_empty
:
# Perhaps they are very different.
self
.
_p
(
"One of them is empty, so just update all the contents."
)
self
.
_xupdateUpdateElement
(
new_element
,
path
)
self
.
_xupdateUpdateElement
(
new_element
,
path
,
nsmap
=
new_element
.
nsmap
)
else
:
# Second, determine if text should be ignored.
old_ignore_text
=
self
.
_checkIgnoreText
(
old_element
)
...
...
@@ -462,7 +465,7 @@ class ERP5Diff:
if
old_ignore_text
!=
new_ignore_text
:
# This means that the semantics of this element is quite different.
self
.
_p
(
"One of them has only text and the other does not, so just update all the contents."
)
self
.
_xupdateUpdateElement
(
new_element
,
path
)
self
.
_xupdateUpdateElement
(
new_element
,
path
,
nsmap
=
new_element
.
nsmap
)
elif
not
old_ignore_text
:
# The contents are only text.
self
.
_p
(
"Both have only text."
)
...
...
@@ -491,7 +494,7 @@ class ERP5Diff:
break
else
:
# There is no matching node. So this element must be removed.
self
.
_xupdateRemoveElement
(
child_path
)
self
.
_xupdateRemoveElement
(
child_path
,
old_node
.
nsmap
)
if
new_len
>
new_start
:
# There are remaining nodes in the new children.
self
.
_xupdateAppendElements
(
new_list
[
new_start
:
new_len
],
path
)
...
...
@@ -508,7 +511,7 @@ class ERP5Diff:
try
:
if
self
.
_result
is
not
None
:
self
.
_result
=
None
self
.
_result
=
etree
.
Element
(
'{%s}modifications'
%
self
.
_ns
,
nsmap
=
{
'xupdate'
:
self
.
_ns
})
self
.
_result
=
etree
.
Element
(
'{%s}modifications'
%
self
.
_ns
,
nsmap
=
{
'xupdate'
:
self
.
_ns
})
self
.
_result
.
set
(
'version'
,
'1.0'
)
if
self
.
_testElements
(
old_root_element
,
new_root_element
):
qname
=
old_root_element
.
xpath
(
'name()'
)
...
...
@@ -517,7 +520,9 @@ class ERP5Diff:
else
:
# These XML documents seem to be completely different...
if
old_root_element
.
tag
!=
new_root_element
.
tag
:
self
.
_xupdateRenameElement
(
new_root_element
.
xpath
(
'name()'
),
'/%s'
%
old_root_element
.
xpath
(
'name()'
))
nsmap
=
old_root_element
.
nsmap
nsmap
.
update
(
new_root_element
.
nsmap
)
self
.
_xupdateRenameElement
(
new_root_element
.
xpath
(
'name()'
),
'/%s'
%
old_root_element
.
xpath
(
'name()'
),
nsmap
)
qname
=
new_root_element
.
xpath
(
'name()'
)
self
.
_testAttributes
(
old_root_element
,
new_root_element
,
'/%s'
%
qname
)
self
.
_compareChildNodes
(
old_root_element
,
new_root_element
,
'/%s'
%
qname
)
...
...
README
View file @
27a9bcf3
...
...
@@ -723,11 +723,11 @@ does not work as bellow example. This is a known bug.
>>> erp5diff.compare(old_xml, new_xml)
>>> erp5diff.output()
<xupdate:modifications xmlns:xupdate="http://www.xmldb.org/xupdate" version="1.0">
<xupdate:remove select="/erp5/object[2]/prefixbis:title"/>
<xupdate:remove
xmlns:prefixbis="http://any_uri_bis"
select="/erp5/object[2]/prefixbis:title"/>
<xupdate:append select="/erp5/object[2]" child="first()">
<xupdate:element name="prefix:title" namespace="http://any_uri"><xupdate:attribute name="prefix:myattr" namespace="http://any_uri">anyvalue</xupdate:attribute>B</xupdate:element>
</xupdate:append>
<xupdate:remove select="/erp5/object[3]/againanotherprefix:title"/>
<xupdate:remove
xmlns:againanotherprefix="http://any_uri"
select="/erp5/object[3]/againanotherprefix:title"/>
<xupdate:append select="/erp5/object[3]" child="first()">
<xupdate:element name="title">A</xupdate:element>
</xupdate:append>
...
...
@@ -762,7 +762,7 @@ does not work as bellow example. This is a known bug.
>>> erp5diff.compare(old_xml, new_xml)
>>> erp5diff.output()
<xupdate:modifications xmlns:xupdate="http://www.xmldb.org/xupdate" version="1.0">
<xupdate:update select="/erp5/object/title/attribute::prefix:attr">B</xupdate:update>
<xupdate:update
xmlns:prefix="http://any_uri"
select="/erp5/object/title/attribute::prefix:attr">B</xupdate:update>
</xupdate:modifications>
25. Modify nodes with Qualified Names at root level
...
...
@@ -784,10 +784,12 @@ does not work as bellow example. This is a known bug.
>>> erp5diff.compare(old_xml, new_xml)
>>> erp5diff.output()
<xupdate:modifications xmlns:xupdate="http://www.xmldb.org/xupdate" version="1.0">
<xupdate:rename select="/erp5:erp5">aaa:erp5</xupdate:rename>
<xupdate:remove select="/aaa:erp5/attribute::a"/>
<xupdate:update select="/aaa:erp5/object/title/attribute::prefix:attr">B</xupdate:update>
<xupdate:rename
xmlns:aaa="http://www.erp5.org/namspaces/aaa" xmlns:erp5="http://www.erp5.org/namspaces/erp5_object"
select="/erp5:erp5">aaa:erp5</xupdate:rename>
<xupdate:remove
xmlns:aaa="http://www.erp5.org/namspaces/aaa"
select="/aaa:erp5/attribute::a"/>
<xupdate:update
xmlns:prefix="http://any_uri" xmlns:aaa="http://www.erp5.org/namspaces/aaa"
select="/aaa:erp5/object/title/attribute::prefix:attr">B</xupdate:update>
</xupdate:modifications>
- 2003-12-04, Yoshinori OKUJI <yo@nexedi.com>
- 2009-09-15, Tatuya Kamada <tatuya@nexedi.com>
- 2009-01-12, Nicolas Delaby <nicolas@nexedi.com>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment