Biztalk XPath格式背后的推理

时间:2014-01-16 12:45:03

标签: xpath biztalk

当您构建BRE词汇表并需要获取节点或值的XPath时,Schema属性是一个方便的源,但是这些xpath的格式有点刺耳。

类似

<ns0:rootnode xmlns:ns0="http://mynamespace.org">
  <ns0:childnode></ns0:childnode>
</ns0:rootnode>

他们使用格式

/*[local-name()='rootnode' namespace-uri()='http://mynamespace.org']/*[local-name()='childnode' namespace-uri()='http://mynamespace.org']

据我了解每个节点它匹配任何(*)然后在条件[]扩展条件以缩小节点名称和名称空间?

我无论如何都不是xpath guru,但我猜这是对命名空间前缀更改的一些保护吗?

但即便如此,为什么不是更短(更清洁)的

/rootnode[namespace-uri()='http://mynamespace.org']/childnode[namespace-uri()='http://mynamespace.org']

1 个答案:

答案 0 :(得分:4)

  

我猜这是对命名空间前缀的一些保护   变化?

实际上,这是整个BizTalk中使用的namespace-agnostic Xpath格式。这允许在不将名称空间加载到XmlNameSpaceManager的情况下解析文档。此外,local-name()的使用排除了名称空间前缀(仅childnode),而name()也包含名称空间别名(例如ns0:childnode)。

所以XPath

 /*[local-name()='rootnode' and namespace-uri()='http://mynamespace.org']
   /*[local-name()='childnode' and namespace-uri()='http://mynamespace.org']

可用于导航以下xml:

<rootnode xmlns='http://mynamespace.org'>
  <childnode xmlns='http://mynamespace.org'>
    .. 
  </childnode>
</rootnode>

所以

/*[local-name()='rootnode' namespace-uri()='http://mynamespace.org']

表示“从/导航到具有元素名称rootnode和名称空间http://mynamespace.org”的子项,等等* matches any element,函数为listed here

不幸的是:

/rootnode[namespace-uri()='http://mynamespace.org']
   /childnode[namespace-uri()='http://mynamespace.org']

不起作用,因为没有名称空间就无法评估/rootnode

可以使用快捷方式,但不明智,例如如果您坚持在xml文档中的所有名称空间中只有一个rootnodechildnode元素,则可以省略namespace-uri(),即

 /*[local-name()='rootnode']/*[local-name()='childnode']

但是如果例如这会破坏如果你的文件是这样的话:

<rootnode xmlns='http://mynamespace.org'>
  <childnode xmlns='http://mynamespace.org'>
  <childnode xmlns='http://anothernamespacehere'>

此外,出于性能原因,在大型文档的BizTalk中,双斜杠是一个特别糟糕的主意。即避免诱惑跳过完整路径导航到达您的叶节点。这是一个坏主意。

 //*[local-name()='childnode' and namespace-uri()='http://mynamespace.org']

<强> TL; DR

IMO,在大多数情况下,将在BizTalk中为您生成与命名空间无关的Xpath导航,您可以放心地让它们独自存在。尽管它们很冗长,但过了一会儿你就会习惯它们而不会真的被它们打扰。