Java 当我删除前缀时,XPath返回null
我在Eclipse下使用Java中的XPath。我正在编写一个soapweb服务,XML使用前缀和名称空间,我想删除前缀,只保留名称空间,因为我更喜欢一个可读性更强的XML文档 当我从XML定义文件中删除前缀并尝试使用XPath查询XML时,XML中的每个节点都会出现null 我的问题是,如果我想使用XPath,是否必须使用前缀?不仅仅是名称空间就足够了吗Java 当我删除前缀时,XPath返回null,java,xml,xpath,xsi,Java,Xml,Xpath,Xsi,我在Eclipse下使用Java中的XPath。我正在编写一个soapweb服务,XML使用前缀和名称空间,我想删除前缀,只保留名称空间,因为我更喜欢一个可读性更强的XML文档 当我从XML定义文件中删除前缀并尝试使用XPath查询XML时,XML中的每个节点都会出现null 我的问题是,如果我想使用XPath,是否必须使用前缀?不仅仅是名称空间就足够了吗 <myrequest xmlns="http://www.mywebsite.com/xml/webservice"
<myrequest
xmlns="http://www.mywebsite.com/xml/webservice"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mywebsite.com/xml/webservice Request.xsd">
<state>
<value>demox</value>
使用XPath 1.0选择命名空间中的元素时,需要在XPath表达式中使用前缀来限定元素名称。因此,即使将XML清理为不使用前缀,而是在XPath表达式中使用默认名称空间声明,也需要使用绑定到默认名称空间的前缀(
http://www.mywebsite.com/xml/webservice
)。如何将前缀绑定到命名空间URI取决于您使用的XPathAPI,我不熟悉JDOM,请亲自检查它的API,了解如何将前缀绑定到命名空间URI
[编辑]方法为。因此,选择任何您喜欢的前缀(例如“pf”),并执行
addNamespace(“pf”)http://www.mywebsite.com/xml/webservice”
,然后在XPath中使用该前缀(例如“pf:myrequest/pf:state/pf:value”)。这是有关几个XPath相关标记的常见问题解答
只要XML文档中存在默认名称空间(如您的情况),XPath表达式中的任何元素名称都必须以绑定到此默认名称空间的前缀作为前缀。绑定在XPath宿主语言中执行,通常使用特定的方法/函数“注册默认名称空间”
必须执行此操作的原因:
只要XPath表达式中有一个不固定的名称,XPath就会将该名称视为属于“无命名空间”
以下是中的规范性文本:
“节点测试中的QName使用表达式上下文中的命名空间声明扩展为扩展名称。这与在开始和结束标记中对元素类型名称进行扩展的方式相同,只是没有使用用xmlns声明的默认名称空间:如果QName没有前缀,则名称空间URI为null(这与扩展属性名称的方式相同)。如果QName的前缀在表达式上下文中没有名称空间声明,则为错误”
因此,在具有默认名称空间的文档上评估/a/b/c
意味着:选择所有位于“无名称空间”中且名为c
的元素,其父元素是位于“无名称空间”中的名为b
的元素,其父元素是xml文档的顶部元素,其名称为a
且位于“无名称空间”中“
由于文档中的所有元素都在其默认名称空间中,而不是“无名称空间”,因此此XPath表达式不选择任何内容
解决方案:
/x:myrequest/x:state/x:value
而不是/myrequest/state/value
<myrequest
xmlns="http://www.mywebsite.com/xml/webservice"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mywebsite.com/xml/webservice Request.xsd">
<state>
<value>demox</value>
如果要使用XPath,则不必使用命名空间前缀。仅使用名称空间就足够了,但是如果注册并使用名称空间前缀,它会使XPath更加简洁、易于阅读和维护
可以使用XPath和元素(即*
)的泛型匹配,并使用谓词过滤器指定本地-name()
和命名空间-uri()
标准,如下所示:
/*[local-name()='myrequest'
and namespace-uri()='http://www.mywebsite.com/xml/webservice']
/*[local-name()='state'
and namespace-uri()='http://www.mywebsite.com/xml/webservice']
/*[local-name()='value'
and namespace-uri()='http://www.mywebsite.com/xml/webservice']
但是,注册名称空间并在XPath中使用名称空间前缀要容易得多。(例如,
/ws:myrequest/ws:state/ws:value
)好问题,+1。有关完整的解释和解决方案,请参见我的答案。