Attribut mit XPath abrufen

344

Bei einer XML-Struktur wie folgt:

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

Wie könnte ich den Wert von lang(wo langsteht engim Buchtitel) für das erste Element erhalten?

GurdeepS
quelle
2
Sehr guter Link bei Verwendung von xpaths test-able.blogspot.ie/2016/04/xpath-selectors-cheat-sheet.html

Antworten:

472

Wie könnte ich den Wert von lang (wobei lang = eng im Buchtitel ist) für das erste Element erhalten?

Verwendung :

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

Dies bedeutet :

Wählen Sie das langAttribut des Titelelements aus, das dem ersten bookuntergeordneten Element des obersten Elements des XML-Dokuments untergeordnet ist.

Verwenden Sie die Standard-XPath-Funktion, um nur den Zeichenfolgenwert dieses Attributs abzurufenstring() :

string(/*/book[1]/title/@lang)
Dimitre Novatchev
quelle
3
@AbhishekAsthana, Das Ergebnis der Auswertung des XPath-Ausdrucks ergibt genau den Zeichenfolgenwert des langAttributs. Wenn das Attribut keine eckigen Klammern enthält, sind sie nicht Teil des Ergebnisses der Auswertung des XPath-Ausdrucks. Ich vermute, dass diese von einem (unangemessenen) Tool hinzugefügt werden, das Sie verwenden.
Dimitre Novatchev
6
Ja, ich habe das Problem herausgefunden. So zeigt es soapUI an, aber diese Klammern werden nicht verwendet, wenn ich den xpath-Wert verwende. Ich habe das viel Zeit gesehen. Das Problem liegt nicht beim Werkzeug. Es befindet sich zwischen dem Stuhl und der Tastatur.
Abhishek Asthana
4
@KorayTugay, der XPath-Ausdruck /*/book[1]/title/@lang wählt einen Knotensatz von 0 oder mehr Attributknoten aus, während der XPath-Ausdruck string(/*/book[1]/title/@lang)bei der Auswertung den Zeichenfolgenwert dieses Knotensatzes erzeugt - und dies ist der Zeichenfolgenwert des ersten (in Dokumentreihenfolge). Knoten aus diesem Knotensatz.
Dimitre Novatchev
4
@KorayTugay, Nein, der erste Ausdruck wählt aus , gibt nicht "zurück" - eine Gruppe von Knoten, und diese Gruppe von Knoten ist keine Zeichenfolge. Ein Knoten ist keine Zeichenfolge - ein Knoten ist ein Knoten in einem Baum . Ein XML-Dokument ist ein Knotenbaum. lang="eng"ist nur eine von vielen Textdarstellungen eines Attributknotens, der einen Namen "lang" hat, nicht zu einem Namespace gehört und einen Zeichenfolgenwert hat, die Zeichenfolge "eng"
Dimitre Novatchev
1
@Vladimir, Wenn das v einem Namespace-uri von say: "my: vvv" entspricht, kann auf dem Host der verwendeten XPath-Engine eine Zuordnung erstellt werden, die myPrefix (möglicherweise v, aber nicht erforderlich) demselben Namespace zuordnet -uri "my: vvv". Und dann wird das Attribut ausgewählt mit: title / @ myPrefix: lang. Wie ein solches Mapping erstellt wird, ist implementierungsspezifisch und muss in der Dokumentation des Hosts der XPath-Engine gelesen werden. Dies geschieht auf eine bestimmte Art und Weise in .NET und auf eine andere Art und Weise, beispielsweise in Saxon. Wenn Sie keine solche Zuordnung haben, verwenden Sie: title / @ * [name () = 'v: lang']
Dimitre Novatchev
47

Vielen Dank! Dies löste ein ähnliches Problem, das ich mit einem Datenattribut in einem Div hatte.

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

Verwenden Sie diesen xpath: //*[@id="prop_sample"]/@data-want

Hoffe das hilft jemand anderem!

smulldino
quelle
6

Sie können unter xPath Muster versuchen,

  XPathExpression expr = xPath.compile("/bookstore/book/title[@lang='eng']")
Sharath
quelle
5
Dadurch werden alle XML- Titelelemente unter / bookstore / book ausgewählt, die ein lang-Attribut mit dem Wert eng und NICHT mit dem Wert lang haben. dh es wählt eine Liste von Elementen aus, kein einziges Attribut
JFK
2

Sie können es auch bekommen

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

Wenn Sie XMLDOM mit JavaScript verwenden, können Sie beispielsweise so etwas codieren

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

und n1.textwird Ihnen den Wert geben"eng"

Vinod Srivastav
quelle
2

Sie können verwenden:

(//@lang)[1]

Dies bedeutet, dass Sie alle Attributknoten mit dem Namen "lang" erhalten und den ersten erhalten.

starcwl
quelle
0

Hier ist der Ausschnitt zum Abrufen des Attributwerts "lang" mit XPath und 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
quelle
0

Wenn Sie PostgreSQL verwenden, ist dies der richtige Weg, um es zu bekommen. Dies ist nur eine Vermutung , wo , wie Sie eine haben Buchtabelle TITEL und PREIS Spalte mit bevölkerten Daten. Hier ist die Abfrage

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