当您构建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']
答案 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文档中的所有名称空间中只有一个rootnode
和childnode
元素,则可以省略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导航,您可以放心地让它们独自存在。尽管它们很冗长,但过了一会儿你就会习惯它们而不会真的被它们打扰。