2010-11-17 7 views
2

Je suis sûr que cela devrait être plus facile que je ne le fais mais j'essaie d'obtenir la réponse suivante de ma source. S'il vous plaît quelqu'un pourrait m'aider avec le xpath? J'essaie de sélectionner les éléments de ligne avec les valeurs "extract". Dans le monde réel, je lis un fichier texte et utilise xml et je veux choisir les lignes qui lisent extrait.XPath trouver des attributs avec des valeurs spécifiques

Source

<line> 
<line number="1">blah</line> 
<line number="2">extract</line> 
<line number="3">blah</line> 
<line number="4">extract</line> 
</line> 

Réponse requise:

<line> 
<line number="2">extract</line> 
<line number="4">extract</line> 
</line> 

ou même

extrait

extrait

serait bien.

Merci beaucoup,

+0

Bonne question, +1. Voir ma réponse pour deux solutions courtes. :) –

+0

Oui, c'est simple. Mais il a besoin de clarification. Si vous voulez une transformation (un résultat XML), vous avez besoin de XSLT. Si vous voulez ** sélectionner ** les nœuds de texte ** contenant ** la chaîne "extraire", alors ceci est possible avec juste XPath. Si vous voulez sélectionner les nœuds de texte avec la valeur de chaîne "extract", cela semble bizarre comme un requeriment ... –

Répondre

0
//line[contains(text(), 'extract')] 

EDIT: Cela fonctionne pour XPath 1.0, et il cherche évidemment la chaîne (plutôt que d'exiger l'égalité).

+0

Cela échouera car, dans ce cas, '// line' n'est pas égal à'/line/line' et la balise supérieure 'line' contient plusieurs chaînes, donc' contains' échoue. Et 'contains()' pourrait se déclencher à de fausses valeurs ex 'contains (text(), 'a')' vous donnera tous les éléments. –

1

Cette (utilisation = si vous utilisez XPath 1.0):

/line/line[text() eq 'extract']/text() 

vous donnera: (See evaluation)

extract 
extract 

La raison pour laquelle //line est pas une bonne idée, est que vous utilisez line étiquettes pour 2 choses (votre top tag line et vos enfants de line) - vous ne devriez pas faire cela: - /. Si vous voulez que les éléments au lieu du texte, vous pouvez écrire:

/line/line[text() eq 'extract'] 

Et enfin, cela vous donnera le nombre (? Il semble que ce soit ce que vous avez vraiment besoin)

count(/line/line[text() eq 'extract']) 
+0

@lasseespeholt: 'eq' est un opérateur XPath 2.0. –

+0

@lasseespeholt: En outre, je suis d'accord avec vous sur la recommandation de ne pas utiliser l'opérateur '//', la solution supprimée '// line [contains (text(), 'extract')]' ** fonctionnera **, car L'élément racine 'line' n'a pas de noeud texte ** enfant ** contenant une chaîne "extract". Dans d'autres cas, ce serait le cas si vous utilisiez une valeur de chaîne (avec la distribution implicite '.' en cours, ou avec la fonction' string() '). –

+0

Je ne sais pas si vous avez raison, mais XQSharp (essayez "Voir l'évaluation") dit que cela ne fonctionne pas mais cela pourrait être mal implémenté. C'est parce que 'text()' n'est pas une chaîne. De plus, 'contains' pourrait se déclencher à de fausses valeurs ex' contains (.., 'a') 'sera vrai avec' blah'. –

0

Depuis votre Le sujet mentionne les attributs (même si votre question ne le fait pas) Je suppose que vous voulez trouver la valeur de l'attribut number pour toutes les lignes correspondantes. Si oui:

/line/line[text()='extract']/@number 
1

Utilisation:

/*/*[.='extract']/text() 

ou même:

//text()[.='extract'] 
Questions connexes