Obtention d'un attribut à l'aide de XPath

344

Étant donné une structure XML comme celle-ci:

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

Comment pourrais-je obtenir la valeur de lang(où langest engdans le titre du livre), pour le premier élément?

GurdeepS
la source
2
très bon lien lors de l'utilisation de xpaths test-able.blogspot.ie/2016/04/xpath-selectors-cheat-sheet.html

Réponses:

473

Comment pourrais-je obtenir la valeur de lang (où lang = eng dans le titre du livre), pour le premier élément?

Utilisation :

/*/book[1]/title/@lang

Cela signifie :

Sélectionnez l' langattribut de l'élément title qui est un enfant du premier bookenfant de l'élément supérieur du document XML.

Pour obtenir uniquement la valeur de chaîne de cet attribut, utilisez la fonction XPath standardstring() :

string(/*/book[1]/title/@lang)
Dimitre Novatchev
la source
3
@AbhishekAsthana, Le résultat de l'évaluation de l'expression XPath produit exactement la valeur de chaîne de l' langattribut. Si l'attribut ne contient pas de crochets, ils ne feront pas partie du résultat de l'évaluation de l'expression XPath. Je suppose que ceux-ci sont ajoutés par un outil (inapproprié) que vous utilisez.
Dimitre Novatchev
6
ouais j'ai compris le problème .. c'est juste comme ça que soapUI l'affiche mais ces crochets ne sont pas utilisés quand j'utilise la valeur xpath. J'ai vu ça beaucoup de temps. Le problème n'est pas avec l'outil ... entre le fauteuil et le clavier.
Abhishek Asthana
4
@KorayTugay, l'expression XPath /*/book[1]/title/@lang sélectionne un ensemble de nœuds de 0 nœud d'attributs ou plus, tandis que l'expression XPath string(/*/book[1]/title/@lang)lorsqu'elle est évaluée, produit la valeur de chaîne de cet ensemble de nœuds - et il s'agit de la valeur de chaîne du premier (dans l'ordre du document) nœud de cet ensemble de nœuds.
Dimitre Novatchev
4
@KorayTugay, Non, la première expression sélectionne , ne "retourne" pas - un ensemble de nœuds, et cet ensemble de nœuds n'est pas une chaîne. Un nœud n'est pas une chaîne - un nœud est un nœud dans une arborescence . Un document XML est un arbre de nœuds. lang="eng"n'est qu'une des nombreuses représentations textuelles d'un nœud d'attribut qui a un nom "lang", n'appartient pas à un espace de noms et a une valeur de chaîne la chaîne "eng"
Dimitre Novatchev
1
@Vladimir, si le v correspond à un uri d'espace de nom de dire: "my: vvv", alors on peut créer dans l'hôte du moteur XPath utilisé un mappage associant myPrefix (peut être v mais pas nécessaire) au même espace de nom -uri "mon: vvv". Et puis l'attribut sera sélectionné en utilisant: title / @ myPrefix: lang. La façon dont un tel mappage est créé est spécifique à l'implémentation et il faut lire dans la documentation de l'hôte du moteur XPath. Cela se fait d'une manière spécifique dans .NET et d'une autre manière, disons en saxon. Si vous ne disposez pas d'un tel mappage, utilisez: title / @ * [name () = 'v: lang']
Dimitre Novatchev
47

Merci! Cela a résolu un problème similaire que j'avais avec un attribut de données dans une Div.

<div id="prop_sample" data-want="data I want">data I do not want</div>

Utilisez ce xpath: //*[@id="prop_sample"]/@data-want

J'espère que ceci aide quelqu'un d'autre!

smulldino
la source
6

Vous pouvez essayer ci-dessous le modèle xPath,

  XPathExpression expr = xPath.compile("/bookstore/book/title[@lang='eng']")
Sharath
la source
5
Cela sélectionnera tous les éléments de titre XML sous / librairie / livre qui ont un attribut lang avec la valeur eng, PAS la valeur de lang. c'est-à-dire qu'il sélectionne une liste d'éléments, pas un seul attribut
JFK
2

Vous pouvez également l'obtenir en

string(//bookstore/book[1]/title/@lang)    
string(//bookstore/book[2]/title/@lang)

bien que si vous utilisez XMLDOM avec JavaScript, vous pouvez coder quelque chose comme

var n1 = uXmlDoc.selectSingleNode("//bookstore/book[1]/title/@lang");

et n1.textvous donnera la valeur"eng"

Vinod Srivastav
la source
2

vous pouvez utiliser:

(//@lang)[1]

cela signifie que vous obtenez tous les nœuds d'attributs avec un nom égal à "lang" et obtenez le premier.

starcwl
la source
0

Voici l'extrait pour obtenir la valeur d'attribut "lang" avec XPath et VTD-XML.

import com.ximpleware.*;
public class getAttrVal {
    public static void main(String s[]) throws VTDException{
        VTDGen vg = new VTDGen();
        if (!vg.parseFile("input.xml", false)){
            return ;
        }
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("/bookstore/book/title/@lang");
        System.out.println(" lang's value is ===>"+ap.evalXPathToString());
    }
}
vtd-xml-author
la source
0

Si vous utilisez PostgreSQL, c'est la bonne façon de l'obtenir. Ceci est juste une hypothèse où, comme vous avez une colonne TITLE et PRICE de table de livre avec des données remplies. Voici la requête

SELECT xpath('/bookstore/book/title/@lang', xmlforest(book.title AS title, book.price AS price), ARRAY[ARRAY[]::TEXT[]]) FROM book LIMIT 1;
Royce
la source