如何比较不同行中具有相同数据的两个xml文件?


9

我有两个文件具有相同的数据,但行不同。

文件1:

<Identities>
    <Identity>
        <Id>048206031415072010Comcast.USR8JR</Id>
        <UID>ccp_test_79</UID>
        <DisplayName>JOSH CCP</DisplayName>
        <FirstName>JOSH</FirstName>
        <LastName>CCP</LastName>
        <Role>P</Role>
        <LoginStatus>C</LoginStatus>
    </Identity>
    <Identity>
        <Id>089612381523032011Comcast.USR1JR</Id>
        <UID>94701_account1</UID>
        <DisplayName>account1</DisplayName>
        <FirstName>account1</FirstName>
        <LastName>94701</LastName>
        <Role>S</Role>
        <LoginStatus>C</LoginStatus>
    </Identity>
</Identities>

文件2:

<Identities>
    <Identity>
        <Id>089612381523032011Comcast.USR1JR</Id>
        <UID>94701_account1</UID>
        <DisplayName>account1</DisplayName>
        <FirstName>account1</FirstName>
        <LastName>94701</LastName>
        <Role>S</Role>
        <LoginStatus>C</LoginStatus>
    </Identity>
    <Identity>
        <Id>048206031415072010Comcast.USR8JR</Id>
        <UID>ccp_test_79</UID>
        <DisplayName>JOSH CCP</DisplayName>
        <FirstName>JOSH</FirstName>
        <LastName>CCP</LastName>
        <Role>P</Role>
        <LoginStatus>C</LoginStatus>
    </Identity>
</Identities>

如果我使用diff file1 file2命令,则会得到以下响应:

1,10d0
<     <Identities>
<         <Identity>
<             <Id>048206031415072010Comcast.USR8JR</Id>
<             <UID>ccp_test_79</UID>
<             <DisplayName>JOSH CCP</DisplayName>
<             <FirstName>JOSH</FirstName>
<             <LastName>CCP</LastName>
<             <Role>P</Role>
<             <LoginStatus>C</LoginStatus>
<         </Identity>
20a11,20
>     <Identities>
>         <Identity>
>             <Id>048206031415072010Comcast.USR8JR</Id>
>             <UID>ccp_test_79</UID>
>             <DisplayName>JOSH CCP</DisplayName>
>             <FirstName>JOSH</FirstName>
>             <LastName>CCP</LastName>
>             <Role>P</Role>
>             <LoginStatus>C</LoginStatus>
>         </Identity>

但是我没有什么不同,因为这些文件在不同的行中具有相同的数据。


通过按行对它们进行排序并进行比较,可以检查它们是否不相等。当然,排序后相等并不意味着它们真正相等,因为排序会破坏XML语法。
jofel

不知道如何解决。它们在文件1a和b以及文件2 b和a中的顺序不同。您可以使用diff -y -B -Z -b --strip-trailing-cr file1 file2
Yurij73

2
您可以尝试xmldiff,但我认为仍然会注意到顺序的变化,因为顺序在通用XML中是相关的。我认为您最好的方法是使用XML解析器和生成器以规范的顺序和格式放置每个文件,然后使用xmldiffdiff。您最喜欢的脚本语言(Perl,Ruby,Python等)的工作。
derobert

Answers:


6

您可以借助一个小型Python脚本来实现所需的功能(您将需要安装Python以及该lxml工具包)。

tagsort.py

#!/usr/bin/python

import sys
from lxml import etree

filename, tag = sys.argv[1:]

doc = etree.parse(filename, etree.XMLParser(remove_blank_text=True))
root = doc.getroot()
root[:] = sorted(root, key=lambda el: el.findtext(tag))
print etree.tostring(doc, pretty_print=True)

该脚本通过第二级元素的内容对XML文档根目录下的第一级元素进行排序,并将结果发送到stdout。叫做:

$ python tagsort.py filename tag

一旦知道了这一点,就可以使用进程替换基于其输出获取差异(我在示例文件中添加了一个元素,并更改了另一个元素以显示非空结果):

$ diff <(python tagsort.py file1 Id) <(python tagsort.py file2 Id)
4a5
>     <AddedTag>Something</AddedTag>
17c18
<     <Role>X</Role>
---
>     <Role>S</Role>


0

它被标记为shell,但是说实话,我更喜欢将脚本语言与解析器一起使用。在这种情况下perlXML::Twig

它是这样的:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

sub compare_by_identity {
   my ( $first, $second ) = @_;
   foreach my $identity ( $first->get_xpath('//Identity') ) {
      my $id = $identity->first_child_text('Id');

      print $id, "\n";
      my $compare_to =
        $second->get_xpath( "//Identity/Id[string()=\"$id\"]/..", 0 );
      if ($compare_to) {
         print "Matching element found for ID $id\n";
         foreach my $element ( $identity->children ) {
            my $tag  = $element->tag;
            my $text = $element->text;
            if ( not $element->text eq $compare_to->first_child_text($tag) ) {
               print "$id, $tag has value $text which doesn't match: ",
                 $compare_to->first_child_text($tag), "\n";
            }
         }
      }
      else {
         print "No matching element for Id $id\n";
      }
   }
}

my $first_file  = XML::Twig->new->parsefile('test1.xml');
my $second_file = XML::Twig->new->parsefile('test2.xml');

compare_by_identity( $first_file,  $second_file );
compare_by_identity( $second_file, $first_file );

我一次明确地比较一个'Identity'元素,并检查一个字段中的所有字段是否以相同的值存在于另一个字段中。

然后将其反转,因为第二个文件可能具有额外的条目。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.