XPath: Wie wähle ich Elemente basierend auf ihrem Wert aus?

221

Ich bin neu in der Verwendung von XPath und dies kann eine grundlegende Frage sein. Bitte nehmen Sie Kontakt mit mir auf und helfen Sie mir bei der Lösung des Problems. Ich habe eine XML-Datei wie diese:

<RootNode>
  <FirstChild>
    <Element attribute1="abc" attribute2="xyz">Data</Element>
  <FirstChild>
</RootNode>

Ich kann das Vorhandensein eines <Element> Tags überprüfen mit:

// Element [@ attribute1 = "abc" und @ attribute2 = "xyz"]

Jetzt möchte ich auch den Wert des Tags auf Zeichenfolge überprüfen "Data" . Um dies zu erreichen, wurde mir gesagt:

// Element [@ attribute1 = "abc" und @ attribute2 = "xyz" und Daten]

Wenn ich den späteren Ausdruck verwende, wird folgende Fehlermeldung angezeigt:

Assertion-Fehlermeldung: Keine Knoten übereinstimmen //Element[@attribute1="abc" and @attribute2="xyz" and Data]

Bitte geben Sie mir Ihren Rat, ob der von mir verwendete XPath-Ausdruck gültig ist. Wenn nicht, wie lautet der gültige XPath-Ausdruck?

vcosk
quelle

Antworten:

329

Die Bedingung unten:

//Element[@attribute1="abc" and @attribute2="xyz" and Data]

prüft auf das Vorhandensein des Elements Daten innerhalb des Elements und nicht auf Elementwertdaten.

Stattdessen können Sie verwenden

//Element[@attribute1="abc" and @attribute2="xyz" and text()="Data"]
SO Benutzer
quelle
25
//Element[@attribute1="abc" and @attribute2="xyz" and .="Data"]

Der Grund, warum ich diese Antwort hinzufüge, ist, dass ich die Beziehung von .und erklären möchte text().

Bei der Verwendung []gibt es zunächst nur zwei Arten von Daten:

  1. [number] um einen Knoten aus dem Knotensatz auszuwählen
  2. [bool] um einen Knotensatz von einem Knotensatz zu filtern

In diesem Fall wird der Wert nach Funktion als boolesch ausgewertet boolean(), und es gibt eine Regel:

Filter werden immer in Bezug auf einen Kontext bewertet.

Wenn Sie eine Zeichenfolge vergleichen text()oder .mit einer Zeichenfolge vergleichen müssen "Data", werden diese zunächst mithilfe einer string()Funktion in einen Zeichenfolgentyp umgewandelt, um dann ein boolesches Ergebnis zu erhalten.

Es gibt zwei wichtige Regeln string():

  1. Die string()Funktion konvertiert eine Knotenmenge in eine Zeichenfolge, indem sie den Zeichenfolgenwert des ersten Knotens in der Knotengruppe zurückgibt, was in einigen Fällen zu unerwarteten Ergebnissen führen kann.

    text()ist ein relativer Pfad, der eine Knotenmenge zurückgibt, die den gesamten Textknoten des aktuellen Knotens (Kontextknoten) enthält, wie z ["Data"]. Wenn es von ausgewertet wird string(["Data"]), wird der erste Knoten des Knotensatzes zurückgegeben, sodass Sie "Daten" nur erhalten, wenn nur ein Textknoten im Knotensatz vorhanden ist.

  2. Wenn die string()Funktion den gesamten untergeordneten Text verketten soll, müssen Sie einen einzelnen Knoten anstelle eines Knotensatzes übergeben.

    Zum Beispiel erhalten wir einen Knotensatz ['a', 'b'], an den Sie den übergeordneten Knoten übergeben string(parent)können. Dieser wird zurückgegeben 'ab'und string(.)in Ihrem Fall wird natürlich eine verkettete Zeichenfolge zurückgegeben "Data".

In beide Richtungen wird nur dann das gleiche Ergebnis erzielt, wenn ein Textknoten vorhanden ist.

宏杰 李
quelle