Java 6アプリケーションの一部として、重複を含め、XMLドキュメント内のすべての名前空間宣言を検索したいと思います。
編集:マーティンの要求に従って、これが私が使用しているJavaコードです:
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
XPathExpression xPathExpression = xPathExpression = xPath.compile("//namespace::*");
NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDomDocument, XPathConstants.NODESET);
このXMLドキュメントがあるとします。
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:ele="element.com" xmlns:att="attribute.com" xmlns:txt="textnode.com">
<ele:one>a</ele:one>
<two att:c="d">e</two>
<three>txt:f</three>
</root>
すべての名前空間宣言を見つけるために、xPath1.0を使用してこのxPathステートメントをXMLドキュメントに適用しました。
//namespace::*
4つの名前空間宣言が見つかります。これは私が期待している(そして望んでいる)ものです。
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
しかし、 xPath 2.0を使用するように変更すると、16個の名前空間宣言(以前の宣言のそれぞれが4回)を取得します。これは、私が期待する(または望む)ものではありません。
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
これと同じ違いは、省略されていないバージョンのxPathステートメントを使用した場合でも見られます。
/descendant-or-self::node()/namespace::*
また、oXygenでテストされているように、さまざまなXMLパーサー(LIBXML、MSXML.NET、Saxon)で見られます。(編集:コメントで後述するように、このステートメントは正しくありません。さまざまなXMLパーサーをテストしていると思っていましたが、実際にはそうではありませんでした。)
質問1: xPath1.0とxPath2.0の違いは何ですか?
質問2: xPath 2.0を使用して望ましい結果を得ることが可能/合理的ですか?
ヒント:同じ名前空間が2回宣言されている場合でも、すべての名前空間宣言が必要なため、distinct-values()
xPath2.0で関数を使用しても目的の結果が返されません。たとえば、次のXMLドキュメントについて考えてみます。
<?xml version="1.0" encoding="UTF-8"?>
<root>
<bar:one xmlns:bar="http://www.bar.com">alpha</bar:one>
<bar:two xmlns:bar="http://www.bar.com">bravo</bar:two>
</root>
望ましい結果は次のとおりです。
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/bar:one[1]/@xmlns:bar - http://www.bar.com
/root[1]/bar:two[1]/@xmlns:bar - http://www.bar.com