Dis*_*ile 8 xml sql-server xpath
我在SQL服务器中有一个包含Xml列的表,我在查询时遇到了问题.我不太了解XPath来确定我的查询是否错误,或者是否因为看起来像是冲突的命名空间.这是一个示例xml:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<!-- snip -->
</s:Header>
<s:Body>
<FetchRequest xmlns="http://www.foobar.org/my/schema">
<Contract xmlns:a="http://www.foobar.org/2014/04/datacontracts"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:RequestedBy>John Doe</a:RequestedBy>
<a:TransactionId>ABC20140402000201</a:TransactionId>
</Contract>
</FetchRequest>
</s:Body>
</s:Envelope>
Run Code Online (Sandbox Code Playgroud)
我想从xml中检索TransactionId.我试过的查询是这样的:
SELECT TOP 100
MessageXml,
MessageXml.value('
declare namespace s="http://www.w3.org/2003/05/soap-envelope";
declare namespace a="http://www.w3.org/2005/08/addressing";
(/s:Envelope/s:Body/FetchRequest/Contract/a:TransactionId)[1]', 'varchar(max)')
FROM dbo.Message
Run Code Online (Sandbox Code Playgroud)
我为MessageXml.value返回NULL.如果我删除s之后的所有内容:Body我似乎得到了一堆串联的文本,但是一旦我添加了FetchRequest,我就会在结果中得到NULL.
我注意到Contract元素定义了a的命名空间,而Envelope也定义了a的命名空间,但我不确定这是否是一个问题.
在给定上面的xml示例的情况下,如何使用XPath查询检索TransactionId?
vit*_*ore 27
我知道答案是可以接受的,但实际上有更简单的方法,如果您需要做的唯一事情就是选择节点值.只需使用*命名空间名称:
SELECT MessageXml
, MessageXml.value('(/*:Envelope/*:Body/*:FetchRequest/*:Contract/*:TransactionId)[1]'
, 'varchar(max)')
FROM dbo.Message
Run Code Online (Sandbox Code Playgroud)
mar*_*c_s 15
你有两个问题:
<FetchRequest>节点上的隐式默认XML命名空间a:前缀的XML命名空间首先在<s:Envelope>节点上定义,并在节点上重新声明<Contract>(在我看来真的是非常糟糕的做法),你需要在节点下面使用第二个声明<Contract>.所以你需要这样的东西(我更喜欢在WITH XMLNAMESPACES()语句中预先定义XML名称空间):
;WITH XMLNAMESPACES('http://www.w3.org/2003/05/soap-envelope' AS s,
'http://www.foobar.org/2014/04/datacontracts' AS a,
'http://www.foobar.org/my/schema' AS fb)
SELECT
MessageXml,
MessageXml.value('(/s:Envelope/s:Body/fb:FetchRequest/fb:Contract/a:TransactionId)[1]', 'varchar(max)')
FROM
dbo.Message
Run Code Online (Sandbox Code Playgroud)
这将输出整个查询和ABC20140402000201第二列的值.
FetchRequest并且Contract在命名空间中http://www.foobar.org/my/schema,别名a在文档中重新定义.你需要:
SELECT TOP 100
MessageXml,
MessageXml.value('declare namespace s="http://www.w3.org/2003/05/soap-envelope";
declare namespace a="http://www.w3.org/2005/08/addressing";
declare namespace f="http://www.foobar.org/my/schema";
declare namespace x="http://www.foobar.org/2014/04/datacontracts";
(/s:Envelope/s:Body/f:FetchRequest/f:Contract/x:TransactionId)[1]', 'varchar(max)')
FROM dbo.Message;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23336 次 |
| 最近记录: |