默认的XML命名空间,JDOM和XPath

问题描述:

我想使用JDOM读取XML文件,然后使用XPath从JDOM文档中提取数据。它创建了Document对象,但是当我使用XPath来查询文档中的元素列表时,我什么也得不到。默认的XML命名空间,JDOM和XPath

我的XML文档在根元素中定义了一个默认名称空间。有趣的是,当我删除默认名称空间时,它成功运行XPath查询并返回我想要的元素。我还需要做些什么才能让我的XPath查询返回结果?

XML:

<?xml version="1.0" encoding="UTF-8"?> 
<collection xmlns="http://www.foo.com"> 
<dvd id="A"> 
    <title>Lord of the Rings: The Fellowship of the Ring</title> 
    <length>178</length> 
    <actor>Ian Holm</actor> 
    <actor>Elijah Wood</actor> 
    <actor>Ian McKellen</actor> 
</dvd> 
<dvd id="B"> 
    <title>The Matrix</title> 
    <length>136</length> 
    <actor>Keanu Reeves</actor> 
    <actor>Laurence Fishburne</actor> 
</dvd> 
</collection> 

爪哇:

public static void main(String args[]) throws Exception { 
    SAXBuilder builder = new SAXBuilder(); 
    Document d = builder.build("xpath.xml"); 
    XPath xpath = XPath.newInstance("collection/dvd"); 
    xpath.addNamespace(d.getRootElement().getNamespace()); 
    System.out.println(xpath.selectNodes(d)); 
} 

的XPath 1.0不支持默认名称空间(的XPath 2.0一样)的概念。 任何前缀不变的标签始终假定为无名称命名空间的一部分。

当使用的XPath 1.0你需要的东西是这样的:

public static void main(String args[]) throws Exception { 
    SAXBuilder builder = new SAXBuilder(); 
    Document d = builder.build("xpath.xml"); 
    XPath xpath = XPath.newInstance("x:collection/x:dvd"); 
    xpath.addNamespace("x", d.getRootElement().getNamespaceURI()); 
    System.out.println(xpath.selectNodes(d)); 
} 
+0

窍门,谢谢! – Michael 2009-02-12 21:10:39

+0

这很好,我花了最后3个小时想知道为什么我的XPath突然不工作,这是。 Pffh! :) – Esko 2009-10-14 13:18:20

我有一个类似的问题,但我是,我有XML输入,其中一些有一个命名空间中定义和其他混合物那没有。为了简化我的问题,我在加载文档后运行了以下JDOM代码片段。

for (Element el : doc.getRootElement().getDescendants(new ElementFilter())) { 
    if (el.getNamespace() != null) el.setNamespace(null); 
} 

删除所有我能使用简单的getChild(“elname”)式的导航或简单的XPath查询的命名空间之后。

我不会推荐这种技术作为一般解决方案,但在我的情况下,它绝对有用。

你也可以做以下

/*[local-name() = 'collection']/*[local-name() = 'dvd']/

Here是有用的XPath查询列表。