2014-11-07 11 views
5

den folgenden XML-Schnipsel Gegeben:Wie können XML-Knotenattribute mit XML :: LibXML aufgelistet werden?

<outline> 
    <node1 attribute1="value1" attribute2="value2"> 
    text1 
    </node1> 
</outline> 

Wie bekomme ich diese Ausgabe?

outline 
node1=text1 
node1 attribute1=value1 
node1 attribute2=value2 

Ich habe in use XML::LibXML::Reader; sah, aber das Modul erscheint lediglich als Zugang zu ihren Namen Werte verwiesen zuzuschreiben. Und Wie bekomme ich die Liste der Attributnamen an erster Stelle?

Antwort

4

Sie finden die Liste der Attribute von $e->findnodes("./@*");

Im Folgenden tut eine Lösung, mit einfachen XML :: LibXML, nicht XML :: LibXML :: Reader, die mit Ihren Testdaten funktionieren. Es kann jedoch für zusätzliche Leerzeichen und gemischte Inhalte empfindlich sein, also testen Sie es mit echten Daten, bevor Sie es verwenden.

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::LibXML; 

my $dom= XML::LibXML->load_xml(IO => \*DATA); 
my $e= $dom->findnodes("//*"); 

foreach my $e (@$e) 
    { print $e->nodeName; 

    # text needs to be trimmed or line returns show up in the output 
    my $text= $e->textContent; 
    $text=~s{^\s*}{}; 
    $text=~s{\s*$}{}; 

    if(! $e->getChildrenByTagName('*') && $text) 
     { print "=$text"; } 
    print "\n"; 

    my @attrs= $e->findnodes("./@*"); 
    # or, as suggested by Borodin below, $e->attributes 

    foreach my $attr (@attrs) 
     { print $e->nodeName, " ", $attr->nodeName. "=", $attr->value, "\n"; } 
    } 
__END__ 
<outline> 
    <node1 attribute1="value1" attribute2="value2"> 
    text1 
    </node1> 
</outline> 
+2

Es gibt viel saubere Möglichkeiten, um die Attribute zu holen. Das Offensichtliche ist 'my @ attrs = $ e-> attributes', das eine Liste aller Attributknoten zurückgibt, aber ein Elementknotenobjekt verhält sich auch wie eine gebundene Hashreferenz, und' keys% $ e' gibt das gesamte Attribut zurück Namen, während '$ e -> {attr_name}' den Wert des Attributs 'attr_name' zurückgibt. – Borodin

+0

Danke, ich habe das nicht in den Dokumenten gefunden, was ich für merkwürdig hielt. Und jetzt sehe ich es unter "Überladen", duh! Ich sehe immer noch keine "Attribute", zumindest in der Dokumentation für XML :: LibXML :: Element. – mirod

+0

Es ist in [XML :: LibXML :: Node'] (https://metacpan.org/module/XML :: LibXML :: Node) – Borodin

5

So etwas sollte Ihnen helfen.

Es ist nicht klar aus Ihrer Frage, ob <outline> das Wurzelelement der Daten ist, oder ob es irgendwo in einem größeren Dokument vergraben ist. Es ist auch unklar, wie allgemein die Lösung sein soll - z. Möchten Sie, dass das gesamte Dokument auf diese Weise gelöscht wird?

Wie auch immer, dieses Programm erzeugt die Ausgabe, die Sie von der gegebenen XML-Eingabe angefordert haben, in einer ziemlich kurzen Art und Weise.

use strict; 
use warnings; 
use 5.014;  #' For /r non-destructive substitution mode 

use XML::LibXML; 

my $xml = XML::LibXML->load_xml(IO => \*DATA); 

my ($node) = $xml->findnodes('//outline'); 

print $node->nodeName, "\n"; 

for my $child ($node->getChildrenByTagName('*')) { 
    my $name = $child->nodeName; 

    printf "%s=%s\n", $name, $child->textContent =~ s/\A\s+|\s+\z//gr; 

    for my $attr ($child->attributes) { 
    printf "%s %s=%s\n", $name, $attr->getName, $attr->getValue; 
    } 
} 

__DATA__ 
<outline> 
    <node1 attribute1="value1" attribute2="value2"> 
    text1 
    </node1> 
</outline> 

Ausgang

outline 
node1=text1 
node1 attribute1=value1 
node1 attribute2=value2