2

给定以下 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stock SYSTEM "new.dtd">
<stock>
    <book num="myBook1">
        <title>Lindsy Boxer</title>
        <author>James Patterson</author>
        <publisher>LittleBig</publisher>
        <price>18.21</price>
        <chapter>
            <title>Alex Cross Is Back - Chapter A</title>
            <paragraph>
                This is the <emph>first</emph> paragraph.
                <image file="alexCrossImage.gif"/>
                afetr image...
            </paragraph>
            <paragraph>
                This is the <emph>second</emph> paragraph.
                <image file="alexCrossImageAnother.gif"/>
                afetr image...
            </paragraph>
        </chapter>
        <chapter>
            <title>Along Came A Spider - Chapter B</title>
            <section>
                <title>Along Came A Spider - Chapter B - section 1</title>
                <paragraph>
                    This is the <emph>first</emph>paragraph for chapter TWO section ONE.
                    <image file="Chapter_B_firstParagraphImage.gif"/>
                    afetr image...
                </paragraph>
                <paragraph>
                    This is the <emph>second</emph> paragraph for chapter TWO section ONE.
                    <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="myBook2">
        <title>Jack Reacher Series</title>
        <author>Lee Child</author>
        <author>Jonny White</author>
        <publisher>Pocket</publisher>
        <price>5.99</price>
        <chapter>
            <title>Jack Reacher - Chapter ONE</title>
        </chapter>
        <chapter>
            <title>Jack Reacher - Chapter TWO</title>
            <paragraph>
                This is the <emph>second</emph> paragraph of SECOND book chapter TWO.
                <image file="Jack_Reacher_Picture_Top_Sniper_US_Army.gif"/>
                afetr image...
            </paragraph>
        </chapter>
    </book>
    <book num="myBook3">
        <title>Alex Cross - Double Cross</title>
        <author>James Patterson</author>
        <publisher>Spectra</publisher>
        <price>17.30</price>
        <chapter>
            <title>Alex Cross - Double Cross - Chapter A</title>
        </chapter>
    </book>
</stock>

当我输入以下查询时:

Object myQuery= xpath.evaluate("stock/book/chapter[3]/preceding-sibling::chapter//title",doc,XPathConstants.NODESET);

我得到的输出为:

<title>Alex Cross Is Back - Chapter A</title>
<title>Along Came A Spider - Chapter B</title>
<title>Along Came A Spider - Chapter B - section 1</title>

但我想要的是当我的 XPath 使用前兄弟轴时,我想以相反的顺序返回节点,即:

         *  <title>Along Came A Spider - Chapter B</title>
         *  <title>Along Came A Spider - Chapter B - section 1</title>
         *  <title>Alex Cross Is Back - Chapter A</title>

所以基本上,如您所见,Java 以混合顺序返回节点,按 XML 文件中节点的顺序,但我需要的是,当 XPath 使用前兄弟轴时,然后反向返回节点命令 。

这不是发生这种“行为”的唯一命令(返回混合节点)。

我的目标是解决这个问题,我试图改变XPath's evalute,但它仍然不起作用。

谁能给出一些指示/提示如何做到这一点?

附言

使用这段代码:

        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        domFactory.setNamespaceAware(true); // never forget this!
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        Document doc = builder.parse("new.xml");
        //create an XPath factory
        XPathFactory factory = XPathFactory.newInstance();
        //create an XPath Object
        XPath xpath = factory.newXPath();
        //***********************************************************//
        Object myQuery= xpath.evaluate("stock/book/chapter[3]/preceding-sibling::chapter//title",doc,XPathConstants.NODESET);
        System.out.println("The Results are:");
        NodeList nodes = (NodeList) myQuery;
        //print the output
        for (int i = 0; i < nodes.getLength(); i++) {
            System.out.println("i: " + i);
            System.out.println("*******");
            System.out.println(nodeToString(nodes.item(i)));
            System.out.println("*******");
        }

我得到了上述结果(混合节点)

4

2 回答 2

3

您希望所选节点以不是其文档顺序的顺序返回。

这在今天的 XPath 1.0 引擎中是不可能的——它们都以文档顺序返回选定的节点。而且 XPath 1.0 没有办法指定任何特殊顺序。

因此,如果您使用的是 XPath 1.0(似乎是这种情况),您将不得不忍受这一点——例如,索引结果不是用增加的索引而是用减少的索引。

在 XPath 2.0 中有序列,您可以编写 XPath 表达式并指定序列中的每个项目

或者(再次在 XPath 2.0 中)您可以只拥有:

reverse(yourExpression)

这将产生相反的项目序列 - 产生的项目序列yourExpression

于 2012-05-11T12:57:00.870 回答
1

事实上,这不是“混合”顺序。这只是XPath 执行的广度优先搜索的结果。正如我所见,您需要深度优先搜索。DFS 结果就像一个普通的搜索结果——首先出现在文档中的内容,将出现在搜索结果的前面。

您可以尝试使用流阅读器StAX自己实现它。那不是 DFS,而是可以为您提供所需结果的普通 XML 阅读器。

于 2012-05-11T11:12:09.340 回答