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


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>

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


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>

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

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?

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
}
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.