jam*_*iss 6 java xml xpath saxon xml-namespaces
作为Java 6应用程序的一部分,我想在XML文档中查找所有名称空间声明,包括任何重复项.
编辑:Per Martin的请求,这是我正在使用的Java代码:
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
XPathExpression xPathExpression = xPathExpression = xPath.compile("//namespace::*");
NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDomDocument, XPathConstants.NODESET);
Run Code Online (Sandbox Code Playgroud)
假设我有这个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>
Run Code Online (Sandbox Code Playgroud)
要查找所有名称空间声明,我使用xPath 1.0将此xPath语句应用于XML文档:
//namespace::*
Run Code Online (Sandbox Code Playgroud)
它找到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
Run Code Online (Sandbox Code Playgroud)
但是,如果我更改为使用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
Run Code Online (Sandbox Code Playgroud)
即使我使用xPath语句的非缩写版本,也会看到同样的差异:
/descendant-or-self::node()/namespace::*
Run Code Online (Sandbox Code Playgroud)
在oXygen中测试的各种XML解析器(LIBXML,MSXML.NET,Saxon)中都可以看到它.(编辑:正如我在后面的评论中提到的,这种说法不正确.虽然我认为我正在测试各种XML解析器,但我真的不是.)
问题1: 为什么从xPath 1.0到xPath 2.0的区别?
问题2: 使用xPath 2.0获得所需结果是否可能/合理?
提示:使用distinct-values()xPath 2.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>
Run Code Online (Sandbox Code Playgroud)
期望的结果是:
/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
Run Code Online (Sandbox Code Playgroud)
我认为这将获得所有名称空间,没有任何重复:
for $i in 1 to count(//namespace::*) return
if (empty(index-of((//namespace::*)[position() = (1 to ($i - 1))][name() = name((//namespace::*)[$i])], (//namespace::*)[$i])))
then (//namespace::*)[$i]
else ()
Run Code Online (Sandbox Code Playgroud)