GSe*_*erg 3 xml asp.net xpath namespaces .net-3.5
我们有一个Web服务,它返回一个非常简单的XML.
<?xml version="1.0"?>
<t:RequestResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://our.website.com/ns/" xmlns:t="http://our.website.com/ns/">
<t:Result>No candy for you today.</t:Result>
<t:Success>false</t:Success>
</t:RequestResult>
Run Code Online (Sandbox Code Playgroud)
调用者使用XMLHTTP获取此XML没问题.但是,由于"引用未声明的命名空间前缀:'t',因此XPath查询不会再次使用此XML
为什么这样?我会说't'前缀有点声明. 该文件是否以任何方式无效?
如果你想知道我们为什么必须首先使用XmlNamespaceDeclarations添加名称空间前缀,那是因为否则生成的文档会被查询,因为它有一个目标名称空间但没有前缀,所以XPath忽略节点名称,因为它们不属于请求的(空)命名空间,我们不想使用像这样的结构"//*[namespace-uri()='http://our.website.com/ns' and local-name()='RequestResult']".
你已经回答了这个问题,但值得理解为什么会这样.
元素所在的命名空间不能仅由命名空间前缀确定.要查找命名元素所在的命名空间t:foo,必须搜索祖先或自定轴,直到找到定义命名空间的最近节点t:.例如:
<t:one xmlns:t="ns-one">
<t:one>
<t:two xmlns:t="ns-two">
<t:two/>
</t:two>
</t:one>
</t:one>
Run Code Online (Sandbox Code Playgroud)
在该文档中,名称所在的每个元素one都在ns-one命名空间中,而名称所在的每个元素two都在ns-two命名空间中.您可以告诉该文档中最深的元素ns-two不是因为t:本质上意味着ns-two,但是因为如果您搜索祖先或自我轴,您使用其xmlns:t上的属性命中的第一个元素- 它的父元素- 会告诉您命名空间.
鉴于此,XPath表达式应//t:*匹配哪些节点?这是不可能的,因为什么命名空间t:映射到整个文档的变化.
此外,名称空间前缀是临时的,但名称空间是永久性的.如果你知道它one在ns-one,你真的,真的不关心它的前缀是否t:或者x:它根本没有前缀而只是一个xmlns属性.
当您使用XPath查询XML文档时,您需要一种方法来指定给定元素所在的命名空间.这就是SelectionNamespacesDOMDocument中的内容,或C#中的命名空间管理器,或者其他适用的内容:它们告诉您什么名称空间XPath查询中的前缀表示.所以,如果我设置前缀a:到ns-one这个XPath //a:one会发现我所有命名元素one的ns-one命名空间,不论他们是怎么使用我搜索文档中的实际前缀.
当你第一次学习它时,这有点违反直觉,但实际上,这是唯一有意义的方法.
| 归档时间: |
|
| 查看次数: |
6758 次 |
| 最近记录: |