Làm thế nào để so sánh hai tệp xml có cùng dữ liệu trong các dòng khác nhau?


9

Tôi có hai tệp có cùng dữ liệu nhưng trong các dòng khác nhau.

Tệp 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>

Tệp 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>

Nếu tôi sử dụng diff file1 file2lệnh tôi sẽ nhận được phản hồi dưới đây:

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>

Nhưng tôi cần không có sự khác biệt, bởi vì các tệp này có cùng dữ liệu trong các dòng khác nhau.


Bằng cách sắp xếp chúng theo chiều dọc và so sánh, bạn có thể kiểm tra xem chúng có bằng nhau không . Tất nhiên, bằng nhau sau khi sắp xếp không có nghĩa là chúng thực sự bằng nhau khi sắp xếp phá hủy cú pháp XML.
jofel

Không biết làm thế nào để giải quyết nó. chúng khác nhau theo thứ tự trong file1 a rồi b và trong file2 b thì a. bạn có thể phơi bày câu hỏi với diff -y -B -Z -b --strip-trailing-cr file1 file2
Yurij73

2
Bạn có thể thử xmldiff, nhưng tôi nghĩ rằng vẫn sẽ nhận thấy thứ tự thay đổi, vì thứ tự có liên quan trong XML chung. Tôi nghĩ cách tiếp cận tốt nhất của bạn là sử dụng trình phân tích cú pháp & trình tạo XML để đặt từng tệp theo thứ tự và định dạng chính tắc, sau đó sử dụng xmldiffhoặc diff. Một công việc cho ngôn ngữ kịch bản yêu thích của bạn (Perl, Ruby, Python, v.v.).
derobert

Câu trả lời:


6

Bạn có thể đạt được những gì bạn muốn với sự trợ giúp của một tập lệnh Python nhỏ (bạn sẽ cần cài đặt Python, cũng như lxmlbộ công cụ).

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)

Kịch bản lệnh này sắp xếp các phần tử mức đầu tiên dưới gốc tài liệu XML theo nội dung của phần tử mức thứ hai, gửi kết quả đến thiết bị xuất chuẩn. Nó được gọi như thế này:

$ python tagsort.py filename tag

Khi bạn đã có được điều đó, bạn có thể sử dụng thay thế quy trình để lấy khác biệt dựa trên đầu ra của nó (Tôi đã thêm một yếu tố và thay đổi một yếu tố khác trong các tệp ví dụ của bạn để hiển thị kết quả không trống):

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

3

Tôi đã có một vấn đề tương tự và cuối cùng tôi đã tìm thấy: /superuser/79920/how-can-i-diff-two-xml-files

Bài đăng đó đề nghị thực hiện một loại xml chính tắc sau đó thực hiện một khác biệt. Những điều sau đây sẽ phù hợp với bạn nếu bạn đang dùng linux, mac hoặc nếu bạn có các cửa sổ giống như cygwin đã cài đặt:

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

0

Nó được gắn thẻ shell, nhưng thực lòng tôi thích sử dụng ngôn ngữ script với trình phân tích cú pháp. Trong trường hợp này perlvới XML::Twig.

Nó đi một cái gì đó như thế này:

#!/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 );

Tôi đang so sánh rõ ràng một yếu tố 'Danh tính' tại một thời điểm và kiểm tra xem tất cả các trường trong một, tồn tại trong một trường khác, có cùng giá trị hay không.

Và sau đó đảo ngược điều đó, bởi vì tệp thứ hai có thể có thêm mục.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.