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、それでも機能しません。

誰かがこれを行う方法についていくつかの指示/ヒントを与えることができますか?

PS

このコードを使用する:

        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 に答える