2009-04-22 3 views
2

D'accord, j'ai un document XML qui ressemble à ceci:Traverse structure xml pour déterminer si un certain nœud de texte existe

<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> 

J'utilise lib-xml Ruby pour l'analyser. Je veux savoir s'il y a un partenaire avec le nom 'Some Name' d'une manière idiomatique rapide et rubis. Comment puis-je le faire dans une ligne ou un code ruby, en supposant que j'ai le document analysé dans une variable nommée document .. De telle sorte que je peux appeler document.find (xpath) pour récupérer des nœuds. J'ai dû le faire plusieurs fois dans des scénarios légèrement différents et maintenant il commence à me déranger.

Je sais que je peux faire ce qui suit (mais son laid)

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") 

mais je trouve cela vraiment moche. J'ai pensé à utiliser l'énumération include? méthode mixin mais cela ne fonctionnera toujours pas parce que j'ai besoin d'obtenir le champ .content de chaque nœud par opposition au nœud réel ... En écrivant cela, je pense à cela (mais il semble quelque peu inefficace quoique élégant)

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

Existe-t-il d'autres façons de procéder?

Répondre

2

Que pensez-vous de cela?

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

J'utiliserais un langage fonctionnant nativement sur XML (XQuery par exemple). Avec XQuery, il est possible de formuler ce type de requêtes sur des données xml de manière concise et élégante.

2

J'ai essayé cette solution:

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

mais je m'y suis une erreur disant que l'expression XPath était invalide. Cependant, je lisais une documentation xpath, il semble que vous pouvez appeler une fonction text() dans l'expression pour obtenir le nœud de texte. J'ai essayé ce qui suit et il semble fonctionner:

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

trouvé est en fait pas un noeud XML, mais un objet vrai/faux si cela fonctionne.

+1

Ce premier XPath fonctionne pour moi avec libxml-ruby et Nokogiri, donc je ne sais pas pourquoi cela vous a donné une erreur XPath invalide. Une note est que '! = Nil' peut ne pas faire ce que vous voulez - même en l'absence de correspondance, vous récupérez une collection. Vous voulez probablement utiliser .empty? pour vérifier si quelque chose a été trouvé. –

+0

@Greg. Je suis d'accord avec toi. Le xpath est un travail. Merci pour le conseil sur l'utilisation de .empty? au lieu de '! = nil' –

+0

Je ne suis pas sûr de ce que j'avais fait de mal mais je peux en fait utiliser cette syntaxe maintenant après avoir essayé à nouveau (peut-être que j'avais un/avant le nom). Avec .empty? mais devra être annulé pour que la logique fonctionne, ainsi: found = document.find ("// partner [name = 'Some Name']"). empty? doit être found =! Document.find ("// partner [name = 'Some Name']"). Empty? –

Questions connexes