2015-04-16 33 views
1

在我们的例子中,我们有动态XML标签像这样的XPath名称空间通配符最佳实践

<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在这种情况下?

回答

2

这里没有必要使用“通配符”,因为这两个示例都是相同的XML - 本地名称为SomeProcessResponse和名称空间URI http://something.com/xyz的元素。它们使用两个不同前缀的事实是不相关的,XPath表达式中使用的前缀绑定取决于XPath库,并且不必与文档中使用的前缀绑定匹配。

您需要使用XPath库提供的功能将前缀(如xyz)绑定到http://something.com/xyz名称空间URI,然后XPath xyz:SomeProcessResponse将匹配这两个示例。

为了给出更具体的答案,我需要知道您正在使用哪种编程语言和哪种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); 
+0

我们使用javascript –

0

如果您在声明命名空间提供命名空间绑定,无论是响应将被正确识别。

如果你需要的是一个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> 
+0

谢谢parakmiakos! –

4

选择名称空间XML元素的最佳做法是指定命名空间而不是通过任何种类的“通配符”机制来忽略它。

对于兼容的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相关联,避免通过通配符命名空间。

+0

谢谢Kenneth! –