як порівняти два 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

Не знаю, як це вирішити. вони відрізняються за порядком у file1 a, потім b, а у file2 b, тоді a. Ви можете викрити питання з файлом diff -y -B -Z -b --strip-trailing-cr1 file2
Yurij73

2
Ви можете спробувати xmldiff, але я думаю, що все одно помітите, що порядок змінюється, оскільки порядок доречний в загальному XML. Я думаю, що найкращим підходом є використання аналізатора XML та генератора, щоб розмістити кожен файл у канонічному порядку та форматі, а потім використовувати xmldiffабо diff. Завдання для вашої улюбленої мови сценаріїв (Perl, Ruby, Python тощо).
derobert

Відповіді:


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>

3

У мене була подібна проблема, і я врешті-решт знайшов: /superuser/79920/how-can-i-diff-two-xml-files

Цей пост пропонує зробити канонічний сорт xml, а потім зробити розл. Наступне має працювати для вас, якщо ви користуєтесь Linux, Mac або якщо у вас встановлено Windows на зразок cygwin:

$ xmllint --c14n File1.xml > 1.xml
$ xmllint --c14n File2.xml > 2.xml
$ diff 1.xml 2.xml

0

Це оболонка з тегом, але, чесно кажучи, я вважаю за краще використовувати мову сценаріїв з аналізатором. У цьому випадку perlс XML::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 );

Я чітко порівнюю один елемент "Ідентичність" за раз і перевіряю, чи всі поля в одному існують в іншому з однаковим значенням.

А потім повернути це, оскільки другий файл може мати додаткові записи.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.