我有以下
XML文档:
<?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>
如何编写XPath 1.0表达式来选择所有包含1个以上图像的书籍?
我试过库存/书籍//图片[2] /祖先::书但是它给出了错误的结果……
是库存/书籍//图像[2]给出每本书中的所有第二张图像?
解决方法
使用:
/*/book[(.//image)[2]]
这将选择所有book元素,这些元素是XML文档的top元素的子元素,并且具有第二个图像后代.
此表达式的评估可能比以//开头的任何表达式更快,因为以//开头的表达式通常会导致遍历整个文档.
它也比以下更有效:
//book[count(.//image)>1]
即使这个表达式被重写不是以//开头.
这是如此,因为在上面的表达式计数(.// image)会导致所有图像后代被计数,而在我们的解决方案中:
(.//image)[2]
仅验证第二个图像后代是否存在.
最后,这是一个基于XSLT的验证:
<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>
当此转换应用于提供的XML文档时:
<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>
评估XPath表达式,并将选定的节点(在本例中只是一个)复制到输出:
<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>