4

我有以下 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 个图像的书籍?

我试过inventory/book//image[2]/ancestor::book但它给出了错误的结果......

inventory/book//image[2]给每本书中的所有第二张图片吗?

4

3 回答 3

5

使用

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

这将选择book作为 XML 文档顶部元素的子元素并且具有第二个image后代的所有元素。

这个表达式的计算速度可能比任何以 开头的表达式都要快//,因为以 开头的表达式//通常会导致整个文档被遍历。

它也比

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

即使这个表达式被重写为不以 . 开头//

之所以如此,是因为在上面的表达式中count(.//image)会计算所有image后代,而在我们的解决方案中:

(.//image)[2]

仅验证是否image存在第二个后代。

最后,这是一个基于 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>
于 2012-05-23T13:00:09.973 回答
4

试试这个

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

所有在某处具有多个图像标签的书籍

于 2012-05-23T10:31:59.683 回答
3

inventory/book//image[2]/如果您的元素中有 2 个或更多image子节点,则会为您获取第二张图像。book尝试:

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

您需要将层次结构向下移动到一个book元素,然后从那里开始查询。谓词(或外行术语的查询)是image从那里查找所有元素——这正是descendant轴的作用。您追加::nodename选择一个特定的后代,就像我们descendant::image查找所有images 一样。最终测试是否确定count(如函数名称所示)是否大于 1。

于 2012-05-23T10:37:04.180 回答