Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 具有多个名称空间的SQL Server Xml查询_Sql Server_Xml_Xpath - Fatal编程技术网

Sql server 具有多个名称空间的SQL Server Xml查询

Sql server 具有多个名称空间的SQL Server Xml查询,sql-server,xml,xpath,Sql Server,Xml,Xpath,我在SQL server中有一个包含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-o

我在SQL server中有一个包含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>
我的MessageXml.value返回NULL。如果我删除s:Body之后的所有内容,我似乎会得到一堆串联的文本,但一旦添加FetchRequest,结果中就会返回NULL

我注意到Contract元素定义了a的名称空间,信封也定义了a的名称空间,但我不确定这是否是一个问题


鉴于上述xml示例,如何使用XPath查询检索TransactionId?

您有两个问题:

  • 您没有遵守
    节点上的隐式默认XML命名空间
  • 带有
    a:
    前缀的XML命名空间首先在
    节点上定义,并在
    节点上重新声明(我认为这是非常糟糕的做法),您需要对
    节点下的任何内容使用第二个声明
所以您需要这样的东西(我更喜欢在
WITH XMLNAMESPACES()
语句中预先定义XML名称空间):


这将为第二列输出整个查询和值
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;

我知道答案是可以接受的,但如果您只需要选择节点值,那么实际上有更简单的方法。只需使用
*
作为名称空间名称:

SELECT MessageXml
     ,  MessageXml.value('(/*:Envelope/*:Body/*:FetchRequest/*:Contract/*:TransactionId)[1]'
                       , 'varchar(max)')
FROM   dbo.Message

我只是说我没有创建XML模式,我只是尝试查询它。在修复谓词并遵循此操作后,我能够得到结果。谢谢你的帮助!感谢您的分享,我一直在努力与多个名称温泉。。这救了我一天,这是我唯一能接受的答案。我在第三方数据库中工作,它们在同一列中使用不同的名称空间,但它们大多遵循相同的模式(至少是我关心的模式路径)。这种方法还意味着更简单/更少的脚本编写,并避免在名称空间发生更改(或进行版本控制以添加更多模式)时随时间而中断。谢谢大家!@MikeTeeVee那正是我找到它的时候。很高兴它有帮助!这正是我需要的,谢谢
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;
SELECT MessageXml
     ,  MessageXml.value('(/*:Envelope/*:Body/*:FetchRequest/*:Contract/*:TransactionId)[1]'
                       , 'varchar(max)')
FROM   dbo.Message