2009-04-22 4 views
2

Okay ich ein XML-Dokument, das ungefähr so ​​aussieht:Traverse XML-Struktur, um zu bestimmen, ob ein bestimmte Textknoten existiert

<xml> 
    <list> 
     <partner> 
     <name>Some Name</name> 
     <status>active</status> 
     <id>0</id> 
     </partner> 
     <partner> 
     <name>Another Name</name> 
     <status>active</status> 
     <id>1</id> 
     </partner> 
    </list> 
    </xml> 

Ich bin mit Ruby lib-xml es zu analysieren. Ich möchte herausfinden, ob es einen Partner mit dem Namen 'Some Name' auf schnelle und rubinartige Weise gibt.

Wie kann ich dies in einer Zeile oder Ruby-Code tun, vorausgesetzt, ich habe ein Dokument in einer Variablen mit dem Namen Dokument analysiert .. So dass ich document.find (xpath) aufrufen kann Knoten abrufen. Ich musste das mehrmals in etwas anderen Szenarien machen und jetzt fängt es an, mich zu ärgern.

Ich weiß, dass ich folgendes tun (aber ihr hässliches)

found = false 
document.find('//partner/name').each do |name| 
    if (name.content == 'Some Name') 
    found = true 
    break 
    end 
end 
assert(found, "Some Name should have been found") 

aber ich finde das wirklich hässlich. Ich dachte über die Verwendung der Aufzählung Include? Mixin-Methode, aber das wird immer noch nicht funktionieren, weil ich das .content-Feld jedes Knotens im Gegensatz zu den tatsächlichen Knoten bekommen muss ... Während ich dies schreibe, habe ich von diesem (aber es scheint ineffizient, wenn auch elegant)

found = document.find('//partner/name').collect{|name| name.content}.member?("Some Name") 

Gibt es andere Möglichkeiten, dies zu tun?

Antwort

2

Was ist damit?

found = document.find("//partner[name='Some Name']").empty? 
0

Ich würde eine Sprache verwenden, die nativ auf XML (XQuery zum Beispiel) funktioniert. Mit XQuery ist es möglich, diese Art von Abfragen über XML-Daten präzise und elegant zu formulieren.

2

habe ich versucht, diese Lösung:

found = document.find("//partner[name='Some Name']") != nil 

aber ich bekam eine Fehlermeldung, der XPath-Ausdruck ungültig war. Allerdings habe ich einige Xpath-Dokumentation gelesen, es sieht so aus, als könnten Sie eine text() - Funktion im Ausdruck aufrufen, um den Textknoten zu erhalten. Ich habe versucht, die folgenden und es scheint zu funktionieren:

found = document.find("//partner/name/text()='Some Name'") 

gefunden tatsächlich ist kein XML-Knoten, sondern ein Wahr/Falsch-Objekt so das funktioniert.

+1

Dieser erste XPath funktioniert sowohl mit libxml-ruby als auch mit Nokogiri, daher weiß ich nicht, warum er einen ungültigen XPath-Fehler verursacht hat. Eine Anmerkung ist, dass "! = Nil" nicht das tut, was Sie wollen - auch wenn keine Übereinstimmungen vorhanden sind, erhalten Sie eine Sammlung zurück. Sie möchten wahrscheinlich .empty verwenden? um zu überprüfen, ob etwas gefunden wurde. –

+0

@Greg. Ich stimme dir zu. Der XPath funktioniert. Danke für den Tipp auf .empty? anstelle von '! = nil' –

+0

bin ich mir nicht sicher, was ich falsch gemacht habe, aber ich kann diese Syntax nun tatsächlich verwenden, nachdem ich es erneut versucht habe (vielleicht hatte ich einen/vor Namen). Verwendung von .empty? Allerdings muss diese Funktion negiert werden, damit die Logik funktioniert: found = document.find ("// partner [name = 'Some Name']"). sollte gefunden =! Document.find ("// partner [name = 'Some Name']"). Leer? –

Verwandte Themen