我正在尝试使用Dom4J解析文档。该文档来自各种提供程序,有时带有名称空间,有时没有。
例如:
<book>
<author>john</author>
<publisher>
<name>John Q</name>
</publisher>
</book>
或
<book xmlns="http://schemas.xml.com/XMLSchemaInstance">
<author>john</author>
<publisher>
<name>John Q</name>
</publisher>
</book>
或
<book xmlns:i="http://schemas.xml.com/XMLSchemaInstance">
<i:author>john</i:author>
<i:publisher>
<i:name>John Q</i:name>
</i:publisher>
</book>
我有一个XPath列表。我将文档解析为Document类,然后使用xpaths搜索它。
Document doc = parseDocument(documentFile);
List<String> XmlPaths = new List<String>();
XmlPaths.add("book/author");
XmlPaths.add("book/publisher/name");
for (int i = 0; i < XmlPaths.size(); i++)
{
String searchPath = XmlPaths.get(i);
Node currentNode = doc.selectSingleNode(searchPath);
assert(currentNode != null);
}
此代码不适用于最后一个文档,即使用名称空间前缀的文档。
我尝试过这些技巧,但似乎都没有。
1)将xpath中的最后一个元素更改为名称空间中性:
/book/:author
/book/[local-name()='author']
/[local-name()='book']/[local-name()='author']
所有这些都抛出异常,说XPATH格式不正确。
2)使用DocumentHelper.createXPath()创建名称空间uris到XPAth;
知道我做错了吗?
仅供参考我正在使用dom4j 1.5版
答案 0 :(得分:2)
您的XPath不包含标记名称。您的案例中的一般语法是
/TAGNAMEPARENT[CONDITION_PARENT]/TAGNAMECHILD[CONDITION_CHILD]
重要的一点是标签名称是必需,而条件是可选。如果您不想指定标记名称,则使用*
作为“任何标记”。可能会对大型XML文件产生性能影响,因为您始终必须迭代节点集而不是使用索引查找。也许@MichaelKay可以对此发表评论。
请改为尝试:
/*[local-name()='book']/*[local-name()='author']