在我们的例子中,我们有像这样的动态XML标记
<ab:SomeProcessResponse xmlns:ab="http://something.com/xyz"
xmlns:cd="http://something.com/lmno">
或者有时我可能会得到回应
<def:SomeProcessResponse xmlns:def="http://something.com/xyz"
xmlns:cd="http://something.com/lmno">
在这种情况下,我应该选择节点SomeProcessResponse
时应遵循的最佳做法是什么?
答案 0 :(得分:4)
选择命名空间XML元素的最佳做法是指定命名空间, not 通过任何类型的&#34;通配符&#34;来忽略它。机构。强>
对于兼容的XPath处理器,始终存在一种机制,允许将名称空间前缀(例如:ab
)绑定到名称空间URI(例如:http://something.com/xyz
)。甚至不必使用与源XML中使用的相同的名称空间前缀(ab
);只有名称空间URI(http://something.com/xyz
)必须匹配。然而,唯一的挑战是XPath本身没有将名称空间前缀绑定到名称空间URI的机制。如何操作取决于库提供的功能(例如:libxml2,javax.xml.xpath等)或托管语言(例如:XSLT)。
为了提供纯XPath答案,或者有时因为(通常是非理性的)对命名空间的厌恶,您有时会看到使用的通配符机制。常见的通配符机制是使用local-name()
仅引用与命名空间无关的本地名称(例如:SomeProcessResponse
)。这样做的问题是它不仅绕过名称空间前缀(例如:ab
),还绕过名称空间URI(http://something.com/xyz
),名称空间URI是名称的组成部分,也是重要的将其他设施与元素相关联的一部分。例如,此类其他工具包括验证和OO类映射。
所以,是的,有躲避命名空间的通配机制,但最佳做法是使用托管语言/库的工具将命名空间前缀与命名空间URI相关联,不通过通配符来避免名称空间。
答案 1 :(得分:2)
这里不需要“通配符”,因为两个示例都是相同的XML - 具有本地名称SomeProcessResponse
和名称空间URI http://something.com/xyz
的元素。它们使用两个不同的前缀这一事实无关紧要,XPath表达式中使用的前缀绑定由XPath库决定,不必与文档中使用的前缀绑定相匹配。
您需要使用XPath库提供的工具将xyz
之类的前缀绑定到http://something.com/xyz
命名空间URI,然后xyz:SomeProcessResponse
的XPath将匹配这两个示例。
为了给出更具体的答案,我需要知道您正在使用哪种编程语言和哪种XPath API。
编辑:在您的评论中,您说您正在使用JavaScript - 在这种情况下,您可以通过将函数传递给document.evaluate
var result = document.evaluate("//xyz:SomeProcessResponse", document, function(prefix) {
if(prefix == "xyz") {
return "http://something.com/xyz";
} else {
return null;
}
}, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
答案 2 :(得分:1)
如果要声明命名空间,则可以正确识别响应。
如果你需要的是xpath
来定位元素而不管名称空间,你可以使用它:
//*[local-name()='SomeProcessResponse']
但请记住,对于以下所有情况都是如此:
<ab:SomeProcessResponse xmlns:ab="http://something.com/xyz" xmlns:cd="http://something.com/lmno">
<def:SomeProcessResponse xmlns:def="http://something.com/xyz" xmlns:cd="http://something.com/lmno">
<ab:SomeProcessResponse xmlns:ab="http://somethingCompletelyDifferent.com/xyz">
<SomeProcessResponse>