1

XPath 2.0をサポートできるように、 Saxon HE 9.4でJavaを使用しています。

次の XML インスタンス ドキュメントがあるとします。

<entities>
    <entity>
        <person>
            James
        </person>
    </entity>
    <entity>
        <legalEntity>
            ACME
        </legalEntity>
    </entity>
</entities>

次のようにして、エンティティ要素タグのリストを取得できることを知っています。

XPathExpression expr = xpath.compile("/entities/entity/*");
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0 ; i < nodes.getLength() ; i++)
    System.out.println("element name = "+ nodes.item(i).getNodeName());

上記は次のように出力されます。

element name = person
element name = legalEntity

... 予想通り。

getNodeNameただし、ロジックは XPath 式自体とメソッドの呼び出しの 2 つの場所に分散しています。私が望むのは、結果の一般的なリストを返す XPath 式です。これは、何らかの一般的なメソッド ( ではないgetNodeName) を呼び出すことで反復処理できます。

このように、すべてのロジックを XPath 式自体に常駐させることができ、私のコードでは XPath 文字列をファイルに保持し、実行時に処理して結果のリストを取得することができます。

XPath 式を試すと/entities/entity/*/name()、最初の値 (人) のみがフェッチされます。

XPathExpression expr = xpath.compile("/entities/entity/*/name()");
System.out.println("element name = "+expr.evaluate(doc));

...そして、それをにキャストしようとすると、実行時にコードが壊れますNodeList:

XPathExpression expr = xpath.compile("/entities/entity/*/name()");
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0 ; i < nodes.getLength() ; i++) {
    ...

(上記は次のエラーで失敗しますnet.sf.saxon.trans.XPathException: Cannot convert XPath value to Java object: required class is org.w3c.dom.NodeList; supplied value has type xs:string:)

したがって、XPath式を結果のリスト (要素タグ、要素値、属性値、タグなど) に評価して、これらの結果を反復処理するコードをすべてのケースで同じにする一般的な方法はありますか?またはの呼び出しを区別する必要はありませんgetNodeName()getNodeValue()?

4

1 に答える 1

2

XPath への JAXP インターフェイスを使用しています。これは XPath 1.0 用に設計されており、XPath 1.0 のデータ型 (文字列、ノード セットなど) のみを認識します。文字列 (またはおそらく QName) のリストを返すクエリを実行する場合は、そのようなデータ型をサポートする API を使用する必要があります。具体的には、Saxon の s9api API に移行する必要があります。

s9api インターフェースでは、XPathSelector オブジェクト ( http://www.saxonica.com/documentation/#!javadoc/net.sf.saxon.s9api/XPathSelectorを参照) が Java の Iterable インターフェースを実装しているため、Java で直接使用できます。結果を一連の XdmItem オブジェクトとして処理する「for-each」命令。XdmItems はノードまたはアトミック値であり、実際には XPath 2.0 データ モデルで定義されている任意のタイプです。

s9api を使用して、Saxon のネイティブ ツリー モデル (s9api DocumentBuilder を使用して構築) または DOM、JDOM、XOM などの外部モデルに対して XPath 式を実行できます。Saxon のネイティブ モデルを使用すると、どの外部モデルよりもはるかに高速です。

于 2013-06-26T10:57:41.307 に答える