2015-10-16 2 views
-1

J'utilise XML::Simple et XML::Dumper. Je suis bien au courant des problèmes entourant l'ancien module. Si je pouvais utiliser une bibliothèque alternative, je le ferais.Analyser les données XML et ajouter un nouvel élément en utilisant XML :: Simple

Ce que je veux accomplir est de charger le XML, puis ajouter des lignes à celui-ci. C'est ma structure XML avant l'exécution du script.

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

Le script, ou ce que je comptais code, devrait charger ce XML à partir d'un fichier, puis ajoutez un élément <param> sur <appearence>. Je l'ai essayé en utilisant ce code:

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; 

Malheureusement, la sortie est la suivante:

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

Non seulement je perds mes originaux <person> balises à <opt> mais cette chaîne HASH REMPLACE ce que je suppose que ce qui était l'élément <param> existant. J'ai lu la documentation pour XML::Simple mais je ne peux pas voir quel argument devrait être utilisé pour empêcher cela.

+1

Je ne peux pas penser à une raison pour laquelle de meilleurs modules XML peuvent être indisponibles pour vous, à moins que quelqu'un tient votre famille en otage. Voulez-vous expliquer le problème? – Borodin

+0

Pas particulièrement. Il existe de nombreuses raisons pour lesquelles les bibliothèques alternatives ne sont pas disponibles dans ce numéro. Depuis quand stackoverflow était-il un site d'interrogation? –

+0

Note: Bien que XML :: Simple soit très mauvais pour l'analyse de XML, il est positivement mauvais pour l'écriture XML. Il va générer du XML qui est différent du XML que vous lisez. Évitez ce module obsolète. – ikegami

Répondre

2

L'utilisation de XML::Simple consiste à utiliser des structures de données Perl, et non XML dans votre code.

Vos problèmes montrent exactement pourquoi le module est déconseillé. Vous devez utiliser ForceArray pour pouvoir modifier facilement le nombre d'éléments d'un parent, et vous devez effacer KeyAttr pour bloquer une gestion spéciale de l'attribut 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); 

A titre de comparaison, la même tâche dans XML::XSH2, une enveloppe autour XML::LibXML:

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

C'est vraiment le pire morceau de XML :: Simple - la plupart des demandes que nous voyons sont _sanely easy_ avec les diverses options disponibles à partir des autres parseurs. – Sobrique

0

1. raison pour laquelle vous perdez des balises est « XMLIN() défausse normalement le nom de l'élément racine Réglage du '. L'option KeepRoot 'à' 1 'provoquera le maintien du nom de l'élément racine. " 2. Après avoir lu le fichier XML à partir du fichier, vous devez utiliser la variable en tant que structure de données 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"; 

Ou

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