如何使用XPath使用Java中的命名空间查询XML? [英] How to query XML using namespaces in Java with XPath?
问题描述
当我的XML看起来像这样(没有 xmlns
)时,我可以轻松地使用XPath查询它,如 / workbook / sheets / sheet [1]
When my XML looks like this (no xmlns
) then I can easly query it with XPath like /workbook/sheets/sheet[1]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook>
<sheets>
<sheet name="Sheet1" sheetId="1" r:id="rId1"/>
</sheets>
</workbook>
但是看起来像这样我就不能
But when it looks like this then I can't
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<sheets>
<sheet name="Sheet1" sheetId="1" r:id="rId1"/>
</sheets>
</workbook>
任何想法?
推荐答案
在第二个示例XML文件中,元素绑定到命名空间。您的XPath正在尝试处理绑定到默认无命名空间命名空间的元素,因此它们不匹配。
In the second example XML file the elements are bound to a namespace. Your XPath is attempting to address elements that are bound to the default "no namespace" namespace, so they don't match.
首选方法是注册命名空间名称空间前缀。它使您的XPath更容易开发,读取和维护。
The preferred method is to register the namespace with a namespace-prefix. It makes your XPath much easier to develop, read, and maintain.
但是,注册命名空间并使用namespace-prefix不是必需的。您的XPath。
您可以制定一个XPath表达式,该表达式使用元素的通用匹配和限制匹配所需的 local-name()
和 namespace-uri()
。例如:
You can formulate an XPath expression that uses a generic match for an element and a predicate filter that restricts the match for the desired local-name()
and the namespace-uri()
. For example:
/*[local-name()='workbook'
and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main']
/*[local-name()='sheets'
and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main']
/*[local-name()='sheet'
and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main'][1]
如你所见,它产生了极长的时间和详细的XPath语句非常难以阅读(和维护)。
As you can see, it produces an extremely long and verbose XPath statement that is very difficult to read (and maintain).
您也可以匹配 local-name()
的元素并忽略命名空间。例如:
You could also just match on the local-name()
of the element and ignore the namespace. For example:
/*[local-name()='workbook']/*[local-name()='sheets']/*[local-name()='sheet'][1]
但是,您冒着匹配错误元素的风险。如果您的XML具有混合词汇表(对于此实例可能不是问题),则使用相同的 local-name()
,您的XPath可以匹配错误的元素并选择错误的内容:
However, you run the risk of matching the wrong elements. If your XML has mixed vocabularies (which may not be an issue for this instance) that use the same local-name()
, your XPath could match on the wrong elements and select the wrong content:
这篇关于如何使用XPath使用Java中的命名空间查询XML?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!