как сравнить два XML-файла, имеющие те же данные в различных строках?

(Отправленный, поскольку новый ответ, так как я не могу прокомментировать и редактирование, является слишком маленьким),

Можно закончить команду "" препятствовать тому, чтобы пользователь выполнил команду с произвольными аргументами.

user ALL=(ALL:ALL) NOPASSWD: /path/to/your/script ""

Теперь sudo /path/to/your/script работы, но sudo /path/to/your/script foo bar сбои.

9
21.11.2018, 16:23
3 ответа

Можно достигнуть того, что Вы хотите с помощью маленького сценария 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>
6
27.01.2020, 20:07

У меня была похожая проблема, и я в конце концов обнаружил: https://superuser.com/questions/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
3
27.01.2020, 20:07

Это оболочка с тегами, но, честно говоря, я предпочитаю использовать язык сценариев с парсером. В данном случае 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 );

Я явно сравниваю один элемент Identity за раз и проверяю, все ли поля в одном существуют в другом с одинаковым значением.

И затем обратное, потому что второй файл может иметь дополнительные записи.

0
27.01.2020, 20:07

Теги

Похожие вопросы