wake-up-neo.net

XPath: Ruft Knoten ab, bei denen der untergeordnete Knoten ein Attribut enthält

Angenommen, ich habe folgendes XML:

<book category="CLASSICS">
  <title lang="it">Purgatorio</title>
  <author>Dante Alighieri</author>
  <year>1308</year>
  <price>30.00</price>
</book>

<book category="CLASSICS">
  <title lang="it">Inferno</title>
  <author>Dante Alighieri</author>
  <year>1308</year>
  <price>30.00</price>
</book>

<book category="CHILDREN">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

<book category="WEB">
  <title lang="en">XQuery Kick Start</title>
  <author>James McGovern</author>
  <author>Per Bothner</author>
  <author>Kurt Cagle</author>
  <author>James Linn</author>
  <author>Vaidyanathan Nagarajan</author>
  <year>2003</year>
  <price>49.99</price>
</book>

<book category="WEB">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

Ich möchte einen xpath ausführen, der alle Buchknoten zurückgibt, die einen Titelknoten mit dem Sprachattribut "it" haben.

Mein Versuch sah ungefähr so ​​aus:

//book[title[@lang='it']]

Aber das hat nicht funktioniert. Ich erwarte, die Knoten zurückzubekommen:

<book category="CLASSICS">
  <title lang="it">Purgatorio</title>
  <author>Dante Alighieri</author>
  <year>1308</year>
  <price>30.00</price>
</book>

<book category="CLASSICS">
  <title lang="it">Inferno</title>
  <author>Dante Alighieri</author>
  <year>1308</year>
  <price>30.00</price>
</book>

Irgendwelche Hinweise? Danke im Voraus.

99
user176872

Versuchen

//book[title/@lang = 'it']

Dies lautet:

  • hole alle book Elemente
    • die mindestens ein title
      • das hat ein Attribut lang
        • mit einem Wert von "it"

Vielleicht finden Sie dies hilfreich - es ist ein Artikel mit dem Titel "XPath in fünf Absätzen" von Ronald Bourret.

Aber ganz ehrlich, //book[title[@lang='it']] und die oben genannten sollten gleichwertig sein, es sei denn, Ihre XPath-Engine weist "Probleme" auf. Es könnte sich also um etwas im Code oder im XML-Beispiel handeln, das Sie uns nicht zeigen. Bei Ihrem Beispiel handelt es sich beispielsweise um ein XML-Fragment. Könnte es sein, dass das Root-Element einen Namespace hat und Sie das in Ihrer Abfrage nicht mitzählen? Und Sie haben uns nur gesagt, dass es nicht funktioniert hat, aber Sie haben uns nicht gesagt, welche Ergebnisse Sie erzielt haben.

155
lavinio

Jahre später, aber eine nützliche Option wäre die Verwendung von XPath-Achsen ( https://www.w3schools.com/xml/xpath_axes.asp ). Insbesondere möchten Sie die Achsen der Nachkommen verwenden.

Ich glaube, dieses Beispiel würde den Trick machen:

//book[descendant::title[@lang='it']]

Auf diese Weise können Sie alle book Elemente auswählen, die ein untergeordnetes title Element enthalten (unabhängig davon, wie tief es verschachtelt ist), dessen Sprachattributwert gleich 'it' ist.

Ich kann nicht sicher sagen, ob diese Antwort für das Jahr 2009 relevant ist oder nicht, da ich nicht zu 100% sicher bin, dass die XPath-Achsen zu diesem Zeitpunkt existierten. Was ich bestätigen kann, ist, dass sie heute existieren und ich habe festgestellt, dass sie in der XPath-Navigation äußerst nützlich sind, und ich bin sicher, dass Sie dies auch tun werden.

46
wes.hysell
//book[title[@lang='it']]

ist eigentlich gleichbedeutend mit

 //book[title/@lang = 'it']

Ich habe es mit vtd-xml versucht, beide Ausdrücke haben das gleiche Ergebnis ausgespuckt ... Welche xpath-Verarbeitungs-Engine haben Sie verwendet? Ich denke, es hat Konformitätsprobleme. Unten ist der Code

import com.ximpleware.*;
public class test1 {
  public static void main(String[] s) throws Exception{
      VTDGen vg = new VTDGen();
      if (vg.parseFile("c:/books.xml", true)){
          VTDNav vn = vg.getNav();
          AutoPilot ap = new AutoPilot(vn);
          ap.selectXPath("//book[title[@lang='it']]");
                  //ap.selectXPath("//book[title/@lang='it']");

          int i;
          while((i=ap.evalXPath())!=-1){
              System.out.println("index ==>"+i);
          }
          /*if (vn.endsWith(i, "< test")){
             System.out.println(" good ");  
          }else
              System.out.println(" bad ");*/

      }
  }
}
9
vtd-xml-author

Ich würde denken, dass Ihr eigener Vorschlag korrekt ist, aber die XML ist nicht ganz gültig. Wenn Sie den //book[title[@lang='it']] Auf <root>[Your"XML"Here]</root> Ausführen, finden die kostenlosen Online-xPath-Tester wie one hier das erwartete Ergebnis.

3
Joakim Byg

Versuchen Sie, diesen xPath-Ausdruck zu verwenden:

//book/title[@lang='it']/..

Das sollte dir alle Buchknoten in "it" lang geben

0
user1113000