XPath gibt nur Elemente zurück, die den Text enthalten, und nicht die übergeordneten Elemente


77

In dieser XML möchte ich übereinstimmen, das Element, das 'match' enthält (random2-Element)

<root>
 <random1>
  <random2>match</random2>
  <random3>nomatch</random3>
 </random1>
</root>

ok, soweit habe ich:

//[re:test(.,'match','i')] (with re in the proper namespace)

Dies gibt random2, random1 und root zurück ... Ich möchte nur "random2" erhalten

irgendwelche Ideen?


Möchten Sie übereinstimmen, wenn es das Wort an einer beliebigen Stelle im Text enthält (z. B. "Überprüfen Sie, ob dies mit dem Wort übereinstimmt ") oder nur Elemente, deren Wert gleich "Übereinstimmung" ist (ignorieren Sie das umgebende Leerzeichen)?
Mads Hansen

es ist nicht so relevant, würde auch funktionieren. Das Problem war hauptsächlich, dass es auch seine Eltern
zurückbrachte

Antworten:


165

Möchten Sie Elemente finden, die "Übereinstimmung" oder gleich "Übereinstimmung" enthalten?

Dadurch werden Elemente mit Textknoten gefunden, die gleich "Übereinstimmung" sind (entspricht keinem der Elemente, da Leerzeichen nach vorne und nach hinten führen random2):

//*[text()='match']

Dadurch werden alle Elemente mit Textknoten gefunden, die gleich "Übereinstimmung" sind, nachdem führende und nachfolgende Leerzeichen (Übereinstimmungen random2) entfernt wurden:

//*[normalize-space(text())='match']

Dadurch werden alle Elemente gefunden, die 'Übereinstimmung' im Textknotenwert (Übereinstimmungen random2und random3) enthalten:

//*[contains(text(),'match')]

Diese XPATH 2.0- Lösung verwendet die matches()Funktion und ein Regex-Muster, das nach Textknoten sucht, die 'match' enthalten und am Anfang der Zeichenfolge (dh ^) oder einer Wortgrenze (dh \W) beginnen und am Ende der Zeichenfolge (dh $) enden. oder eine Wortgrenze. Der dritte Parameter ibewertet das Regex-Muster ohne Berücksichtigung der Groß- und Kleinschreibung. (Streichhölzer random2)

//*[matches(text(),'(^|\W)match($|\W)','i')]

Ihre zweite Aussage ist nicht wahr. Hinweis: Nehmen Sie ein Element mit mehr als einem Textknoten, dessen erster Textknoten keine "Übereinstimmung" enthält.
Dimitre Novatchev

Danke @Dimitre. Aktualisiert mit etwas, das robuster sein sollte.
Mads Hansen

Eigentlich möchte ich eine bestimmte Abfrage mit regulärem Ausdruck wie '^ ma (t | T) ausführen. *' Kann ich die erste verwenden? //*[text()='^ma(t|T).* '] richtig?
Julian

Wenn Sie Regex verwenden möchten, verwenden Sie so etwas wie das letzte Beispiel. Regex wird in XSLT 1.0 nicht unterstützt, daher benötigen Sie ein XSLT 2.0-Stylesheet und einen XSLT 2.0-Prozessor (wie Saxon), um es zu verwenden.
Mads Hansen

Ich glaube, //*/text()[normalize-space(.)='match']/parent::*sollte //*[normalize-space(text())='match']oder//*[normalize-space(./text())='match']
neaumusic

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.