Thursday, October 08, 2009

Das Kreuz mit XML::Simple

Im Perl-Forum gab es gerade mal wieder einen Post zu XML::Simple. Der Fragesteller wollte wissen, wie man nach einer Änderung der XML-Daten auf die Inhalte zugreifen kann. Ursprünglich sah es so aus:

<root><receive>
<audiorate>##Network.Advanced.Receive.AudioRate##</audiorate>
<videorate>##Network.Advanced.Receive.VideoRate##</videorate>
</receive>
</root>


Da kann man mit

use XML::Simple;
# ...
my $doc = XMLin( $xml );
print $doc->{receive}->{audiorate};


bequem auf Inhalte zugreifen.

Jetzt hat sich aber wie gesagt das XML geändert:

<root>
<receive item="1">
<audiorate item="1">##Network.Advanced.Receive.AudioRate##</audiorate>
<videorate item="1">##Network.Advanced.Receive.VideoRate##</videorate>
</receive>
<receive item="2">
<audiorate item="2">##Network.Advanced.Receive.AudioRate##</audiorate>
<videorate item="2">##Network.Advanced.Receive.VideoRate##</videorate>
</receive>
</root>


Und schon funktioniert der Code nicht mehr. Ein Riesennachteil an XML::Simple ist, dass man bei Änderungen am XML auch den Code ändern muss.

Bei dem geänderten XML kann man dann so auf die Inhalte zugreifen:

for my $rx_val ( @{$doc->{receive}} ) {
print $rx_val->{audiorate}->{content};
}


Generell empfiehlt es sich, sich die Datenstruktur mal genauer anzuschauen.

#!/usr/bin/perl

use strict;
use warnings;
use XML::Simple;
use Data::Dumper;

my $xml = do { local $/; <data> };
my $doc = XMLin( $xml );

print Dumper $doc;

__DATA__
<root>
<receive item="1">
<audiorate item="1">##Network.Advanced.Receive.AudioRate##</audiorate>
<videorate item="1">##Network.Advanced.Receive.VideoRate##</videorate>
</receive>
<receive item="2">
<audiorate item="2">##Network.Advanced.Receive.AudioRate##</audiorate>
<videorate item="2">##Network.Advanced.Receive.VideoRate##</videorate>
</receive>
</root>


Ich benutze (fast) nur noch XML::LibXML.

Übrigens ist "Perl und XML" ein Thema in der nächsten Ausgabe des Perl-Magazins "$foo", die am 01. November erscheint.

3 comments:

rainboxx said...

5 zu 0 für XML::LibXML! Was ich mich schon mit den anderen XML-Modulen rumgeschlagen habe... Die einen können nur lesen, nicht schreiben oder haben bei letzterem dauernd Probleme, oder man muss, abhängig davon, wieviele Nodes in einer Node sind, ganz anderen Code auf den Tisch legen. Das geht ja mal gar nicht!

Also: verwendet nur noch XML::LibXML ;-)

Anonymous said...

XML::LibXML hat leider wenig Tutorials - aber es ist wirklich sehr schnell - persoenlich bin ich ein XPath-Fan - besonders da es mit Sketchpath ein tolles Tool gibt, in dem ich das XML Dokument laden und dann die Query fuer das angeklickte Element automatisch bekomme...

/Matthias

ReneeB said...

Ich helfe mir immer wieder mit dem Cheatsheet falls ich mal was suche.

Wobei man sehr vieles nicht braucht, wenn man den angenehmen Weg über XPath geht.