xpath finde, ob ein Knoten existiert

201

Wie können Sie mithilfe einer xpath-Abfrage feststellen, ob überhaupt ein Knoten (Tag) vorhanden ist?

Zum Beispiel, wenn ich sicherstellen musste, dass eine Website-Seite die richtige Grundstruktur wie / html / body und / html / head / title hat

EddyR
quelle
Vielleicht ist es besser, XML-Schema mit obligatorischen Elementangaben zu verwenden? Überprüfen Sie also, ob ein Dokument es verwendet oder nicht.
Abatishchev

Antworten:

321
<xsl:if test="xpath-expression">...</xsl:if>

so zum Beispiel

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>
Patrick McDonald
quelle
41
Überrascht von einer so hohen Bewertung, da die Frage die Verwendung von XSLT überhaupt nicht spezifiziert.
tjmoore
Das ist großartig, aber was ist, wenn ich überprüfen wollte, ob es existiert ODER leer ist?
SearchForKnowledge
3
@SearchForKnowledge, sollten Sie dies wahrscheinlich als neue Frage bei SO stellen, aber als Kurzanleitung: html/body and not(html/body/node())(dh testen Sie einfach, ob es vorhanden ist und keine untergeordneten Knoten oder Textknoten enthält).
Abel
71

Versuchen Sie den folgenden Ausdruck: boolean(path-to-node)

Annesley
quelle
3
Dies ist genau das, was ich brauchte, wenn ich XPath in Python mit lxml verwendete.
Iain Samuel McLean Elder
1
Dies war ein Vergnügen beim
Erstellen von Regelbedingungen
3
Dies ist die richtige Antwort in dem Sinne, dass dies im Gegensatz zu den meisten anderen Antworten tatsächlich eine XPath-Abfrage ist.
Paul Etherton
48

Patrick ist korrekt, sowohl bei der Verwendung von xsl:ifals auch bei der Syntax zur Überprüfung der Existenz eines Knotens. Wie Patricks Antwort impliziert, gibt es jedoch kein xsl-Äquivalent zu if-then-else. Wenn Sie also eher nach einem if-then-else suchen, ist es normalerweise besser, xsl:chooseund zu verwenden xsl:otherwise. Die Beispielsyntax von Patrick wird also funktionieren, aber dies ist eine Alternative:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>
gkrogers
quelle
+1 für die Notiz if-then-else, auch was ist mit if-else if-else? Kann ich test="somexpath"in davenpcjs Antwort in die 2. setzen, wann ich es machen soll if-else if-else?
AabinGunz
3
@Abhishek Ja, Sie können mehr xsl setzen: wenn mit anderen Bedingungen und eine Anweisung mit mehreren Zweigen. Stellen Sie es sich eher wie ein SELECT als wie ein Wenn-Dann-Sonst vor, mit xsl: ansonsten als Standard:.
Davenpcj
Das ist großartig, aber was ist, wenn ich überprüfen wollte, ob es existiert ODER leer ist?
SearchForKnowledge
13

Möglicherweise ist es besser, eine Auswahl zu verwenden, Ihre Ausdrücke nicht mehr als einmal eingeben (oder möglicherweise falsch eingeben) zu müssen, und Sie können weitere unterschiedliche Verhaltensweisen verfolgen.

Ich benutze sehr oft count(/html/body) = 0, da die spezifische Anzahl von Knoten interessanter ist als die Menge. Zum Beispiel ... wenn es unerwartet mehr als einen Knoten gibt, der Ihrem Ausdruck entspricht.

<xsl:choose>
    <xsl:when test="/html/body">
         <!-- Found the node(s) -->
    </xsl:when>
    <!-- more xsl:when here, if needed -->
    <xsl:otherwise>
         <!-- No node exists -->
    </xsl:otherwise>
</xsl:choose>
davenpcj
quelle
Wie im obigen Code angegeben, können weitere xsl: when-Klauseln hinzugefügt werden, um das Verhalten zu ändern und mehrere Bedingungen auf unterschiedliche Weise zu behandeln.
Davenpcj
count(/html/body) = 0 Genie! : DI verwenden Sie es als /html[count(/body)=0]/someNodefür die Auswahl, someNodewann /body(oder was auch immer) fehlt
Stefan Rogin
1
@clickstefan, /html[count(/body)=0]wird nie etwas auswählen, es können nicht zwei Wurzelknoten in XML sein. Vielleicht hast du gemeint /html[count(body)=0], was das gleiche wäre wie /html[not(body)]oder /html[not(exists(body))].
Abel
@Abel ja, / html [count (// body) = 0] oder wie du gesagt hast, beschämend, aber ja, ich habe kein richtiges Beispiel gegeben
Stefan Rogin
4

Ich arbeite in Ruby und mit Nokogiri hole ich das Element und schaue, ob das Ergebnis Null ist.

require 'nokogiri'

url = "http://somthing.com/resource"

resp = Nokogiri::XML(open(url))

first_name = resp.xpath("/movies/actors/actor[1]/first-name")

puts "first-name not found" if first_name.nil?
bcolfer
quelle
3

Eine Variation bei Verwendung von xpath in Java mit count ():

int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}
user324898
quelle