web-dev-qa-db-ja.com

子ノードでXPathを実行する

XPathルックアップによって返されたノードでXPathルックアップを実行しようとしていますが、期待どおりに機能していないようです。ドキュメントの子ノードで実行されたXPathは、ドキュメントのルートノード(例、インベントリタグ。)、提供されたノードのルートの代わりに。

ここに何かが足りませんか?私はXPathが初めてです。

また、「// book [author = 'Neal Stephenson'/title」とだけ答えないでください。正当なユースケースがありますが、これは簡単な例です。

コードスニペット

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("src/main/Java/books.xml");

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

Node book = (Node) xpath.evaluate("//book[author='Neal Stephenson']", doc, XPathConstants.NODE);
Node title = (Node) xpath.evaluate("/title", book, XPathConstants.NODE); // I get null here.
Node inventory = (Node) xpath.evaluate("/inventory", book, XPathConstants.NODE); // this returns a node.

book.xml

<inventory>
<book year="2000">
    <title>Snow Crash</title>
    <author>Neal Stephenson</author>
    <publisher>Spectra</publisher>
    <isbn>0553380958</isbn>
    <price>14.95</price>
</book>

<book year="2005">
    <title>Burning Tower</title>
    <author>Larry Niven</author>
    <author>Jerry Pournelle</author>
    <publisher>Pocket</publisher>
    <isbn>0743416910</isbn>
    <price>5.99</price>
</book>

<book year="1995">
    <title>Zodiac</title>
    <author>Neal Stephenson</author>
    <publisher>Spectra</publisher>
    <isbn>0553573862</isbn>
    <price>7.50</price>
</book>

<!-- more books... -->

</inventory>
49
Jeeyoung Kim

/fooは、ルートノードに基づいて選択し、xpathを評価しているコンテキストを無視します。 foo(スラッシュなし)はあなたが望むものです;現在のノードに基づいて選択します。

https://www.w3schools.com/xml/xpath_syntax.asp は、もう少し情報を提供します。

49
Pete Hodgson

xpathでは、「。」 (ドット)は現在のドキュメントを表します。したがって、「。」の後にXPATH文字列を記述します。 (ドット)。

例:

"./title"

または

".//title"

あなたが望むものなら、なんでも....

スラッシュの削除は、ノードの子である場合にのみ機能します。 //(現在のドキュメントのどこでも)機能を使用する場合はどうなりますか?

そのため、ドット(。)を使用します

上記の回答もありがとう:)。

25
Salman

サブクエリの先頭のスラッシュを削除するだけで大​​丈夫です。したがって、"//book"、そしてそこからはただ"title""inventory" etc子ビットを取得します。

7
Corey Porter

Javaの実装で実際に奇妙なのは、ドキュメントから抽出されたNodeがまだ親ドキュメントを参照していることです(Node.getOwnerDocument()を参照) xpathはこれを使用してルートを見つけます。

他の人は、スラッシュを削除してルートから実際にnotを開始するようにxpathを変更する方法に言及しています。

同様の問題がありましたが、ルートドキュメントと子ノードの両方を処理するxpathが必要でした(_/title_のようなxp​​athを使用)。解決策はcloneノード:Node.cloneNode(true)でした。 Nodeその親ドキュメントをシェイクオフにする)trueパラメーターに注意してください。

...最終的に、パフォーマンスが大幅に低下し、別のxpathを使用してNodeとDocumentが優先されました。

4
mauhiz