Ottenere l'attributo usando XPath


344

Data una struttura XML come questa:

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

Come ho potuto ottenere il valore di lang(dove langè engin titolo del libro), per il primo elemento?


2
ottimo collegamento quando si utilizza xpaths test-able.blogspot.ie/2016/04/xpath-selectors-cheat-sheet.html

Risposte:


473

Come potrei ottenere il valore di lang (dove lang = eng nel titolo del libro), per il primo elemento?

Utilizzare :

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

Questo significa :

Seleziona l' langattributo dell'elemento title che è figlio del primo bookfiglio dell'elemento superiore del documento XML.

Per ottenere solo il valore di stringa di questo attributo, utilizzare la funzione XPath standardstring() :

string(/*/book[1]/title/@lang)

3
@AbhishekAsthana, Il risultato della valutazione dell'espressione XPath produce esattamente il valore di stringa langdell'attributo. Se l'attributo non contiene parentesi quadre, non faranno parte del risultato della valutazione dell'espressione XPath. La mia ipotesi è che questi vengano aggiunti da uno strumento (inappropriato) che si sta utilizzando.
Dimitre Novatchev

6
Sì, ho capito il problema ... è così che soapUI lo mostra ma quelle parentesi non vengono usate quando uso il valore xpath. L'ho visto un sacco di tempo. Il problema non è con lo strumento ... tra la sedia e la tastiera.
Abhishek Asthana,

4
@KorayTugay, l'espressione XPath /*/book[1]/title/@lang seleziona un set di nodi di 0 o più nodi di attributo, mentre l'espressione XPath string(/*/book[1]/title/@lang)quando valutata, produce il valore di stringa di questo set di nodi - e questo è il valore di stringa del primo (nell'ordine del documento) nodo da questo set di nodi.
Dimitre Novatchev,

4
@KorayTugay, No, la prima espressione seleziona , non "restituisce" - un set di nodi, e questo set di nodi non è una stringa. Un nodo non è una stringa: un nodo è un nodo in un albero . Un documento XML è un albero di nodi. lang="eng"è solo una delle molte rappresentazioni testuali di un nodo di attributo che ha un nome "lang", non appartiene a uno spazio dei nomi e ha un valore di stringa la stringa "eng"
Dimitre Novatchev,

1
@Vladimir, Se la v corrisponde a un namespace-uri di dire: "my: vvv", allora si può creare nell'host del motore XPath usando una mappatura che associa myPrefix (può essere v ma non necessario) allo stesso spazio dei nomi -uri "mio: vvv". E quindi l'attributo verrà selezionato usando: title / @ myPrefix: lang. Il modo in cui viene creata una tale mappatura è specifico dell'implementazione e si deve leggere nella documentazione dell'host del motore XPath. Questo viene fatto in modo specifico in .NET e in un altro modo diciamo in Saxon. Se non si dispone di tale mappatura, utilizzare: title / @ * [name () = 'v: lang']
Dimitre Novatchev

47

Grazie! Ciò ha risolto un problema simile che avevo con un attributo di dati all'interno di un Div.

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

Usa questo xpath: //*[@id="prop_sample"]/@data-want

Spero che questo aiuti qualcun altro!


6

Puoi provare sotto il modello xPath,

  XPathExpression expr = xPath.compile("/bookstore/book/title[@lang='eng']")

5
Ciò selezionerà tutti gli elementi del titolo XML in / bookstore / book che hanno un attributo lang con il valore eng, NON il valore di lang. cioè seleziona un elenco di elementi, non un singolo Attributo
JFK

2

Puoi anche ottenerlo

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

anche se se usi XMLDOM con JavaScript puoi scrivere qualcosa di simile

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

e n1.textti darà il valore"eng"


2

Puoi usare:

(//@lang)[1]

questo significa che ottieni tutti i nodi di attributi con nome uguale a "lang" e ottieni il primo.


0

Ecco lo snippet per ottenere il valore dell'attributo "lang" con XPath e 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());
    }
}

0

Se stai usando PostgreSQL, questo è il modo giusto per ottenerlo. Questo è solo un ipotesi in cui si dispone di un libro tavolo TITOLO e PREZZO colonna con i dati popolate. Ecco la domanda

SELECT xpath('/bookstore/book/title/@lang', xmlforest(book.title AS title, book.price AS price), ARRAY[ARRAY[]::TEXT[]]) FROM book LIMIT 1;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.