2013-07-09 6 views
2

У меня есть XML, который содержит & apos; for 'и т. д. Когда я разбираю его при использовании XML :: Twig и затем распечатываю его снова, все & apos; печатаются как '. Кроме того, XML :: Twig, похоже, переупорядочивает атрибуты, чтобы поместить их в алфавитном порядке. С точки зрения XML они эквивалентны, но я хочу внести небольшой набор изменений в XML и использовать diff, чтобы подтвердить, что сделаны только те изменения, которые я намеревался. Есть ли способ заставить XML :: Twig ничего не менять, кроме того, что я явно меняю?Я хочу XML :: Twig, чтобы напечатать точно, что было разобрано в

Вот мой XML:

<?xml version="1.0" encoding="utf-8"?> 
<System> 
    <P C="C" B="B" A="A">&apos;&lt;&gt;&quot;&amp;</P> 
    <P A="A" B="B" C="C">'&lt;>"&amp;</P> 
</System> 

И Perl:

my $twig = new XML::Twig(KeepSpaces => 'true'); 
$twig->parsefile("test.xml"); 
$twig->print(); 

А вот что распечатана:

<?xml version="1.0" encoding="utf-8"?> 
<System> 
    <P A="A" B="B" C="C">'&lt;>"&amp;</P> 
    <P A="A" B="B" C="C">'&lt;>"&amp;</P> 
</System> 
+3

Как насчет «унификации» как оригинала, так и выхода перед сравнением? Мы используем 'xmllint --c14n FILE.XML | xmllint --format -' для обоих, а затем для стандартного 'diff'. – choroba

+0

Это мысль. Я бы предпочел не нормализовать XML, чтобы сделать diff, но это может быть разумным резервом. – JamieC

ответ

7

Похоже, что вариант keep_encoding делает трюк:

use strict; 
use warnings; 
use XML::Twig; 

my $twig = XML::Twig->new( 
        keep_spaces  => 1, 
        keep_encoding => 1, 
        keep_atts_order => 1, 
); 
$twig->parsefile('test.xml'); 
$twig->print; 

Обновление: Улучшено в ответ на комментарий mirod.

+1

также 'keep_atts_order => 1' – mirod

+1

, и если вы знаете, какие элементы вы хотите изменить, вы можете использовать' twig_roots => {elt => sub {change_elt ($ _); $ _-> flush}}, twig_print_outside_roots => 1' – mirod