/ / XPath 1.0 Check Count - XML, XPath, Count, Nodes

XPath 1.0 check count - xml, xpath, Anzahl, Knoten

Ich habe das folgende XML-Dokument:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE inventory SYSTEM "books.dtd">
<inventory>
<book num="b1">
<title>Snow Crash</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<price>14.95</price>
<chapter>
<title>Snow Crash - Chapter A</title>
<paragraph>
This is the <emph>first</emph> paragraph.
<image file="firstParagraphImage.gif"/>
afetr image...
</paragraph>
<paragraph>
This is the <emph>second</emph> paragraph.
<image file="secondParagraphImage.gif"/>
afetr image...
</paragraph>
</chapter>
<chapter>
<title>Snow Crash - Chapter B</title>
<section>
<title>Chapter B - section 1</title>
<paragraph>
This is the <emph>first</emph> paragraph of section 1 in chapter B.
<image file="Chapter_B_firstParagraphImage.gif"/>
afetr image...
</paragraph>
<paragraph>
This is the <emph>second</emph> paragraph of section 1 in chapter B.
<image file="Chapter_B_secondParagraphImage.gif"/>
afetr image...
</paragraph>
</section>
</chapter>
<chapter>
<title>Chapter C</title>
<paragraph>
This chapter has no images and only one paragraph
</paragraph>
</chapter>
</book>
<book num="b2">
<title>Burning Tower</title>
<author>Larry Niven</author>
<author>Jerry Pournelle</author>
<publisher>Pocket</publisher>
<price>5.99</price>
<chapter>
<title>Burning Tower - Chapter A</title>
</chapter>
<chapter>
<title>Burning Tower - Chapter B</title>
<paragraph>
This is the <emph>second</emph> paragraph of chapter B in the 2nd book.
<image file="Burning_Tower_Chapter_B_secondParagraphImage.gif"/>
afetr image...
</paragraph>
</chapter>
</book>
<book num="b3">
<title>Zodiac</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<price>7.50</price>
<chapter>
<title>Zodiac - Chapter A</title>
</chapter>
</book>
<!-- more books... -->
</inventory>

Wie schreibe ich einen XPath 1.0-Ausdruck, um alle Bücher mit mehr als einem Bild auszuwählen?

Ich habe es versucht inventory/book//image[2]/ancestor::book aber es gibt falsches Ergebnis ...

ist inventory/book//image[2] Gib allen das 2. Bild in jedem Buch?

Antworten:

5 für die Antwort № 1

Benutzen:

/*/book[(.//image)[2]]

Dies wählt alles aus book Elemente, die dem obersten Element des XML-Dokuments untergeordnet sind und eine Sekunde haben image Nachkomme.

Dieser Ausdruck wird möglicherweise schneller ausgewertet als jeder Ausdruck beginnend mit //, weil ein Ausdruck beginnt mit // In der Regel wird das gesamte Dokument durchlaufen.

Es ist auch effizienter als:

//book[count(.//image)>1]

auch wenn dieser Ausdruck von Anfang an neu geschrieben wurde //.

Dies ist so, weil im obigen Ausdruck count(.//image) bewirkt alles image Nachkommen gezählt werden, während in unserer Lösung:

(.//image)[2]

nur überprüft, dass eine Sekunde image Nachkomme existiert.

Zum Schluss hier eine XSLT-basierte Verifikation:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="node()|@*">
<xsl:copy-of select="/*/book[(.//image)[2]]"/>
</xsl:template>
</xsl:stylesheet>

Wenn diese Umwandlung auf das bereitgestellte XML-Dokument angewendet wird:

<inventory>
<book num="b1">
<title>Snow Crash</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<price>14.95</price>
<chapter>
<title>Snow Crash - Chapter A</title>
<paragraph>
This is the <emph>first</emph> paragraph.
<image file="firstParagraphImage.gif"/>
afetr image...
</paragraph>
<paragraph>
This is the <emph>second</emph> paragraph.
<image file="secondParagraphImage.gif"/>
afetr image...
</paragraph>
</chapter>
<chapter>
<title>Snow Crash - Chapter B</title>
<section>
<title>Chapter B - section 1</title>
<paragraph>
This is the <emph>first</emph> paragraph of section 1 in chapter B.
<image file="Chapter_B_firstParagraphImage.gif"/>
afetr image...
</paragraph>
<paragraph>
This is the <emph>second</emph> paragraph of section 1 in chapter B.
<image file="Chapter_B_secondParagraphImage.gif"/>
afetr image...
</paragraph>
</section>
</chapter>
<chapter>
<title>Chapter C</title>
<paragraph>
This chapter has no images and only one paragraph
</paragraph>
</chapter>
</book>
<book num="b2">
<title>Burning Tower</title>
<author>Larry Niven</author>
<author>Jerry Pournelle</author>
<publisher>Pocket</publisher>
<price>5.99</price>
<chapter>
<title>Burning Tower - Chapter A</title>
</chapter>
<chapter>
<title>Burning Tower - Chapter B</title>
<paragraph>
This is the <emph>second</emph> paragraph of chapter B in the 2nd book.
<image file="Burning_Tower_Chapter_B_secondParagraphImage.gif"/>
afetr image...
</paragraph>
</chapter>
</book>
<book num="b3">
<title>Zodiac</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<price>7.50</price>
<chapter>
<title>Zodiac - Chapter A</title>
</chapter>
</book>
<!-- more books... -->
</inventory>

Der XPath-Ausdruck wird ausgewertet und die ausgewählten Knoten (in diesem Fall nur einer) werden in die Ausgabe kopiert:

<book num="b1">
<title>Snow Crash</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<price>14.95</price>
<chapter>
<title>Snow Crash - Chapter A</title>
<paragraph>
This is the <emph>first</emph> paragraph.
<image file="firstParagraphImage.gif"/>
afetr image...
</paragraph>
<paragraph>
This is the <emph>second</emph> paragraph.
<image file="secondParagraphImage.gif"/>
afetr image...
</paragraph>
</chapter>
<chapter>
<title>Snow Crash - Chapter B</title>
<section>
<title>Chapter B - section 1</title>
<paragraph>
This is the <emph>first</emph> paragraph of section 1 in chapter B.
<image file="Chapter_B_firstParagraphImage.gif"/>
afetr image...
</paragraph>
<paragraph>
This is the <emph>second</emph> paragraph of section 1 in chapter B.
<image file="Chapter_B_secondParagraphImage.gif"/>
afetr image...
</paragraph>
</section>
</chapter>
<chapter>
<title>Chapter C</title>
<paragraph>
This chapter has no images and only one paragraph
</paragraph>
</chapter>
</book>

4 für die Antwort № 2

versuche es mit diesem

//book[count(.//image)>1]

Alle Bücher, die mehr als ein Image-Tag irgendwo haben


3 für die Antwort № 3

inventory/book//image[2]/ Erhältst du das zweite Bild, vorausgesetzt, es gibt 2 oder mehr image untergeordnete Knoten in Ihrem book Element. Versuchen:

   //inventory/book[count(descendant::image) > 1]

Sie müssen in der Hierarchie nach unten zu a wechseln book element und starten Sie von dort aus Ihre Abfrage. Das Prädikat (oder die Abfrage in Laienbegriffen) besteht darin, nach allen zu suchen image Elemente von da an - das ist genau das, was die descendant Achse tut. Sie hängen an :: und nodename um einen bestimmten Nachkommen auszuwählen, wie wir es mit tun descendant::image nach allen suchen images. Der letzte Test, um sicherzustellen, ob die count (wie der Name der Funktion andeutet) ist größer als 1 oder nicht.