2015-10-16 2 views
-1

Я использую XML::Simple и XML::Dumper. Я хорошо знаю проблемы, связанные с прежним модулем. Если бы я мог использовать альтернативную библиотеку, я бы это сделал.Анализ данных XML и добавление нового элемента с использованием XML :: Simple

Что я хочу достичь, это загрузить XML, а затем добавить строки к нему. Это моя структура XML до запуска скрипта.

<person> 
    <appearance> 
    <param name="height" value="6,3"/> 
    </appearence> 
</person> 

сценарий, или то, что я намеревался кода, необходимо загрузить этот XML из файла, а затем присоединять <param> элемент на <appearence>. Я попытался его с помощью этого кода:

use warnings; 

use XML::Simple; 
use XML::Dumper; 

my $xml = XMLin('xml_import.xml'); 

$xml->{appearence} .= qq{<param name="age" value="22" />}; 
my $new_xml = XMLout($xml, noattr => 1, NoEscape => 1); 

open(FILE, ">xml_import.xml"); 
print FILE $new_xml; 
close FILE; 

К сожалению, выход на это:

<opt> 
    <appearence>HASH(0x1722190)<param name="age" value="22" /></appearence> 
</opt> 

Я не только потерять свои оригинальные <person> теги к <opt> но HASH строка заменяет то, что я полагаю, что было существующий элемент <param>. Я прочитал документацию для XML::Simple, но я не могу определить, какие аргументы следует использовать для предотвращения этого.

+1

Я не могу придумать причину, почему лучше модули XML могли быть недоступны для вас, если кто-то держит вашу семью в заложники. Вы хотите объяснить проблему? – Borodin

+0

Не особенно. Существует много причин, по которым альтернативные библиотеки недоступны в этой проблеме. С каких пор был stackoverflow сайт для опроса? –

+0

Примечание. Хотя XML :: Simple довольно плохо для синтаксического анализа XML, для написания XML это ужасно ужасно. Он будет генерировать XML, который отличается от XML, который вы читаете. Избегайте этого устаревшего модуля. – ikegami

ответ

2

Точка использования XML::Simple - это использовать структуры данных Perl, а не XML в вашем коде.

Ваши проблемы показывают, почему именно модуль обескуражен. Вы должны использовать ForceArray, чтобы иметь возможность легко изменять количество элементов в родительском объекте, и вам нужно очистить KeyAttr, чтобы заблокировать специальную обработку атрибута name.

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

use XML::Simple; 

my $xml = << '__XML__'; 
<person> 
    <appearance> 
    <param name="height" value="6,3"/> 
    </appearance> 
</person> 
__XML__ 

my $simple = XMLin($xml, ForceArray => 1, 
         KeepRoot => 1, 
         KeyAttr => [], 
       ); 

push @{ $simple->{person}[0]{appearance}[0]{param} }, { name => 'age', 
                 value => 22, 
                 }; 
print XMLout($simple, KeepRoot => 1); 

Для сравнения, та же задача в XML::XSH2, обертка XML::LibXML:

open file.xml ; 
my $p := insert element param append /person/appearance ; 
set $p/@name 'age' ; 
set $p/@value 22 ; 
save :b ; 
+0

Это действительно худший бит XML :: Simple. Большинство запросов, которые мы видим, являются _insanely easy_ с различными вариантами, доступными из других парсеров. – Sobrique

0

1. Причиной вы потеряете тег является «XMLin() обычно отбрасывает имя корневого элемента Настройки. KeepRoot 'до' 1 'приведет к сохранению имени корневого элемента. "

2. После чтения xml из файла следует использовать переменную в виде структуры данных perl.

#! /usr/bin/perl 

use strict; 
use XML::Simple qw(:strict); 
use Data::Dumper; 

my $xml = XMLin('xml_import.xml', KeepRoot => 1, KeyAttr => ["param"], ForceArray => ["param"]); 
print '-----$xml-----', "\n", Dumper($xml), "\n"; 

my $new_node = {'name' => 'age', 'value' => '22'}; 
push $xml->{person}->{appearance}->{param}, $new_node; 
print '-----Insert a new node to $xml-----', "\n", Dumper($xml), "\n"; 

my $new_xml = XMLout($xml, NoAttr => 1, NoEscape => 1, KeepRoot => 1, KeyAttr => []); 
print '-----$new_xml-----', "\n", $new_xml, "\n"; 

Или

#! /usr/bin/perl 

use strict; 
use XML::Simple qw(:strict); 
use Data::Dumper; 

my $xml = XMLin('xml_import.xml', KeepRoot => 1, KeyAttr => {param => "+name"}, ForceArray => ["param"]); 
print '-----$xml-----', "\n", Dumper($xml), "\n"; 

my $new_node = {'name' => 'age', 'value' => '22'}; 
$xml->{person}->{appearance}->{param}->{age} = $new_node; 
print '-----Insert a new node to $xml-----', "\n", Dumper($xml), "\n"; 

my $new_xml = XMLout($xml, NoAttr => 1, NoEscape => 1, KeepRoot => 1, KeyAttr => {param => "+name"}); 
print '-----$new_xml-----', "\n", $new_xml, "\n"; 
Смежные вопросы