比较两个XML文档,通过区分它们的文本,忽略结构,并在del > /< INS>标签中包装更改的文本。
xml_diff的Python项目详细描述
比较两个xml文档中的文本,并用<del>和<ins>标记来标记差异。
这是大约7年的努力的结果,试图得到正确的和简单的编码。我在govtrack.us<;https://www.govtrack.us>;上使用了这样或那样的代码来比较bill文本。
这种比较完全忽略了这两个xml文档的结构。它只对文本内容进行逐字比较,然后返回原始文档,并将更改的文本包装到新的<del>和<ins>包装元素中。
然后将这些文档连接起来形成一个新文档,并在标准输出上打印新文档。或者将其用作库,并使用两个lxml.etree.Element节点(文档的根)调用compare自己。
脚本是用python 3编写的。
示例
比较这两个文档:
<html> Here is <b>some bold</b> text. </html>
以及:
<html> Here is <i>some italic</i> content that shows how <tt>xml_diff</tt> works. </html>
产量:
<documents> <html> Here is <b>some <del>bold</del></b><del> text</del>. </html> <html> Here is <i>some <ins>italic</ins></i><ins> content that shows how </ins><tt><ins>xml_diff</ins></tt><ins> works</ins>. </html> </documents>
在ubuntu上,获取依赖项:
apt-get install python3-lxml libxml2-dev libxslt1-dev
要进行快速比较,请获取google的diff-match补丁库<;https://code.google.com/p/google-diff-match-patch/>;,该库由@leutloff<;https://github.com/leutloff/diff-match-patch-cpp-stl>;重新编写并加速,然后由我转换为python扩展模块<;https://github.com/JoshData/diff_match_patch-python>;:
pip3 install diff_match_patch_python
或者如果由于任何原因无法安装,请使用纯python库:
pip3 install diff-match-patch
这里也是<;https://code.google.com/p/google-diff-match-patch/source/browse/trunk/python3/diff_match_patch.py>;。xml_diff将使用安装的任何一个。
最后,安装此模块:
pip3 install xml_diff
然后从命令行调用模块:
python3 -m xml_diff --tags del,ins doc1.xml doc2.xml > changes.xml
或者使用python中的模块:
import lxml.etree from xml_diff import compare dom1 = lxml.etree.parse("doc1.xml").getroot() dom2 = lxml.etree.parse("doc2.xml").getroot() comparison = compare(dom1, dom2)
这两个DOM被修改到位。
可选参数
compare函数接受其他可选的关键字参数:
merge是一个布尔值(默认为false),指示比较函数是否应执行合并。如果为true,dom1将不仅包含<del>节点,而且还包含<ins>节点,同样,dom2将不仅包含<ins>节点,而且还包含<del>节点。尽管这两个dom现在将包含关于更改的相同语义信息和相同的文本内容,但每个dom都保留其原始结构,因为比较只针对文本而不是结构。新的ins/del节点包含来自其他文档(包括整个子树)的内容,因此不能保证最终文档在此操作之后符合任何特定的结构模式。
word_separator_regex(默认值r"\s+|[^\s\w]")是用于分隔单词的正则表达式。默认情况下,在一行中的一个或多个空格和非单词字符的单个实例上进行拆分。
differ是一个函数,它接受两个参数(text1, text2),并返回以(operation, text_length)形式的元组形式给出的差分操作的迭代器,其中operation是"="(文本中没有更改)、"+"(插入text2的文本)或"-"(从text1中删除的文本)之一。(有关默认differ的工作原理,请参见xml diff/\u init.py的default_differ函数。)
tags是两个标记名元组,用于删除和插入的内容。默认值是('del', 'ins')。
make_tag_func是一个函数,它接受一个参数"ins"或"del",并返回一个新的lxml.etree.Element以插入到dom中来包装更改的内容。如果给定,则忽略tags参数。