xpath znajdź, jeśli węzeł istnieje


201

Używając zapytania xpath, jak sprawdzić, czy w ogóle istnieje węzeł (znacznik)?

Na przykład, jeśli muszę upewnić się, że strona internetowa ma poprawną podstawową strukturę, taką jak / html / body i / html / head / title


Może lepiej jest użyć schematu XML ze wskazaniem elementów obowiązkowych? Sprawdź, czy dokument go używa, czy nie.
abatishchev

Odpowiedzi:


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

więc na przykład

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>

41
Zaskoczony tak wysoką oceną, biorąc pod uwagę, że pytanie w ogóle nie określa użycia XSLT.
tjmoore

To jest niesamowite, ale co jeśli chcę sprawdzić, czy istnieje LUB jest puste?
SearchForKnowledge

3
@SearchForKnowledge, powinieneś prawdopodobnie zadać to pytanie jako nowe pytanie w SO, ale jako szybki przewodnik: html/body and not(html/body/node())(tj. Po prostu sprawdź, czy istnieje i nie zawiera żadnych węzłów podrzędnych ani węzłów tekstowych).
Abel,


48

Patrick ma rację, zarówno w użyciu xsl:if, jak i w składni do sprawdzania istnienia węzła. Jednak, jak sugeruje odpowiedź Patryka, nie ma żadnego odpowiednika xsl dla „jeśli-to-inaczej”, więc jeśli szukasz czegoś bardziej podobnego do „jeśli-to-inaczej”, zwykle lepiej jest użyć xsl:choosei xsl:otherwise. Tak więc przykładowa składnia Patricka będzie działać, ale jest to alternatywa:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>

+1 za zauważenie if-then-else, a co z tego if-else if-else? Czy w odpowiedzi davenpcj mogę umieścić test="somexpath"na drugim miejscu, kiedy to zrobić if-else if-else?
AabinGunz,

3
@Abhishek Tak, możesz umieścić więcej xsl: w przypadku innych warunków i mieć instrukcję wielobranżową. Pomyśl o tym bardziej jak o WYBORZE niż o tym, jeśli-a-jeszcze, z xsl: w przeciwnym razie jako domyślną :.
davenpcj

To jest niesamowite, ale co jeśli chcę sprawdzić, czy istnieje LUB jest puste?
SearchForKnowledge

13

Być może lepiej będzie skorzystać z wyboru, nie musisz wpisywać (lub być może pomylić) swoich wyrażeń więcej niż jeden raz i pozwala ci śledzić dodatkowe różne zachowania.

Bardzo często używam count(/html/body) = 0, ponieważ konkretna liczba węzłów jest bardziej interesująca niż zestaw. Na przykład ... gdy nieoczekiwanie jest więcej niż 1 węzeł pasujący do Twojego wyrażenia.

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

Jak wskazano w powyższym kodzie, więcej xsl: when można dodać klauzule, aby zmienić zachowanie i obsługiwać wiele warunków na różne sposoby.
davenpcj

count(/html/body) = 0 geniusz! : DI używam go /html[count(/body)=0]/someNodedo wybierania, someNodekiedy /body(lub cokolwiek) brakuje
Stefan Rogin

1
@clickstefan, /html[count(/body)=0]nigdy niczego nie wybierze, w XML nie mogą znajdować się dwa węzły główne. Może miałeś na myśli /html[count(body)=0], co byłoby takie samo jak /html[not(body)]lub /html[not(exists(body))].
Abel

@Abel tak, / html [count (// body) = 0] lub jak to powiedziałeś, haniebne, ale tak nie podałem właściwego przykładu
Stefan Rogin

4

Pracuję w Ruby i za pomocą Nokogiri pobieram element i sprawdzam, czy wynik jest zerowy.

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

Odmiana przy użyciu xpath w Javie przy użyciu count ():

int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.