2011-01-10 8 views
0

Ich versuche herauszufinden, wie man XML durchläuft, aber ich habe viel gelesen und ich bleibe immer noch stecken. Hier ist die Info:einfache XML-Frage für Perl - wie spezifische Elemente abgerufen werden

Ich bin mit dem wordnik api zum Abrufen von XML mit XML :: Simple:

$content = get($url); 
$r = $xml->XMLin("$content"); 

Die eigentliche XML sieht wie folgt aus:

<definitions> 
− 
<definition sequence="0" id="0"> 
− 
<text> 
To withdraw one's support or help from, especially in spite of duty, allegiance, or responsibility; desert: abandon a friend in trouble. 
</text> 
<headword>abandon</headword> 
<partOfSpeech>verb-transitive</partOfSpeech> 
</definition> 
− 
<definition sequence="1" id="0"> 
− 
<text> 
To give up by leaving or ceasing to operate or inhabit, especially as a result of danger or other impending threat: abandoned the ship. 
</text> 
<headword>abandon</headword> 
<partOfSpeech>verb-transitive</partOfSpeech> 
</definition> 
− 
<definition sequence="2" id="0"> 
− 
<text> 
To surrender one's claim to, right to, or interest in; give up entirely. See Synonyms at relinquish. 
</text> 
<headword>abandon</headword> 
<partOfSpeech>verb-transitive</partOfSpeech> 
</definition> 
− 
<definition sequence="3" id="0"> 

...

Was ich will, ist einfach der Sprachteil der ERSTEN Definition. Ich verwende diesen Code, aber es wird die PO LETZTEN Definition:

if($r->{definition}->{0}->{partOfSpeech}) { 
     $pos = $r->{definition}->{0}->{partOfSpeech}; 
    } 
else { $pos = $r->{definition}->{partOfSpeech}; } 

Ich bin mir ziemlich peinlich dies, da ich weiß, dass es ein offensichtlich besserer Weg, es zu tun. Ich würde gerne etwas so einfaches wie dieses Arbeiten bekommen, damit ich die Elemente allgemeiner durchgehen könnte. BUt es funktioniert einfach nicht für mich (keine Ahnung, was zu verweisen). Ich habe viele Variationen der folgenden versucht - das ist nur mein letzter Versuch:

while (my ($k, $v) = each %{$r->{definitions}->{definition}[0]->{sequence}->{partOfSpeech}}) { 
    $v =~ s/'/'"'"'/g; 
    $v = "'$v'"; 
    print "export $k=$v\n"; 
} 

Schließlich, wenn ich "print Dumper ($ r)" tun es gibt mir dies:

$VAR1 = { 
      'definition' => { 
          '0' => { 
           'partOfSpeech' => 'noun', 
           'sequence' => '6', 
           'text' => 'A complete surrender of inhibitions.', 
           'headword' => 'abandon' 
           } 
         } 
     }; 

(Und dieses "Nomen", das Sie sehen, ist die letzte (6.) Definition/Teil des Sprachelements.


Basierend auf Antwort des RC unten, sieht meine neuen Code wie folgt aus:

$content = get($url); 
$r = $xml->XMLin("$content", KeyAttr => { definition => 'sequence'}); 
while (my ($k, $v) = each %{$r->{definition}}) { 
    $v=$r->{definition}->{$k}->{partOfSpeech}; 
    print "export $k=$v\n"; 
} 

Dies gibt die folgenden:

export 6='noun' 
export 4='verb-transitive' 
export 1='verb-transitive' 
export 3='verb-transitive' 
export 0='verb-transitive' 
export 2='verb-transitive' 
export 5='noun' 

Also das ist gut und es ist der Export die korrekte Paare. Aber jetzt ist das Problem, dass die Bestellung aus ist (was sehr wahrscheinlich das Problem von Wordnik und kein Programmierproblem ist). Wie sortiere ich das mit einem Schlüssel? Etwas wie das?

sort($r->{definition}); 

Antwort

3

Von XML::Simple doc:

Anmerkung 1: Der Standardwert für 'KeyAttr' ist [ 'name', 'Schlüssel', 'id']. Wenn nicht am Eingang oder am Ausgang ausgegeben werden soll, müssen Sie diese Option auf eine leere Liste auf deaktivieren, um die Funktion zu deaktivieren.

Ich denke, Hinzufügen von KeyAttr => { definition => 'sequence' } zu XMLin Optionen könnte Ihr Problem beheben.

+0

RC thx - das ist wirklich nützlich ist und bewegt es in die richtige Richtung. aber ich habe jetzt eine neue (kleinere) Frage. Siehe meinen editierten Beitrag für angehängte Informationen. – Jeff

+0

ersetzt 'while (my ($ k, $ v) = jedes% {$ r -> {definition}}) {' durch 'foreach my $ k (Sortierschlüssel% {$ r -> {definition}}) {' sollte den Trick tun –

+0

yup - vielen Dank! – Jeff

3

Es ist auch möglich XML::Twig zu verwenden Datei für Sie zu durchqueren und helfen, die Daten zu extrahieren:

use XML::Twig; 

my $content = do { local $/; <DATA> };  # get data 

XML::Twig->new(twig_handlers => { 
    definition => sub { 
     warn "---\n", 
      "sequence = ",  $_->att('sequence'), "\n", 
      "text = ",   $_->first_child_trimmed_text('text'), "\n", 
      "headword = ",  $_->first_child_trimmed_text('headword'), "\n", 
      "partOfSpeech = ", $_->first_child_trimmed_text('partOfSpeech'), "\n"; 
     $_->purge; 
    }, 
})->parsestring($content); 

Dies ist auch effizienter, weil ganz Struktur nicht im Speicher (die purge Methode geladen werden muss ist die Reinigung der verarbeiteten Daten für Sie).

Verwandte Themen