sql 服务器使用命名空间解析 xml
sql server parse xml with namespace
我正在尝试解析以下 xml 以获取 s:Body 标记之后的第一个标记(在本例中我正在寻找字符串 queryEE
,在其他情况下具有相同 Envelope/Body 结构的消息会有所不同)
我开始玩这样的东西:
declare @text varchar(max)
set @text = N'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queryEE xmlns="http://xx.gob.gcaba.xx/">
<codeEE xmlns="">xxxx</codeEE>
</queryEE>
</s:Body>
</s:Envelope>'
declare @x xml
set @x = cast(@text as xml)
select @x.query('/s:Envelope')
但我收到错误消息:
Msg 2229, Level 16, State 1, Line 16
XQuery [query()]: The name "s" does not denote a namespace.
好像我在命名空间方面遇到了问题
当我尝试 select @x.query('/Envelope')
时,我根本没有得到任何结果
感谢我从@shnugo 那里得到的答案,我终于可以用以下方法解决它:
select @x.value('local-name((/*:Envelope/*:Body/*)[1])','nvarchar(100)')
在使用 xquery for xml 和命名空间时再次声明您的命名空间。
declare @text varchar(max)
set @text = N'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queryEE xmlns="http://xx.gob.gcaba.xx/">
<codeEE xmlns="">xxxx</codeEE>
</queryEE>
</s:Body>
</s:Envelope>'
declare @x xml
set @x = cast(@text as xml)
select @x.query('declare default element namespace "http://schemas.xmlsoap.org/soap/envelope/";
/Envelope')
这样试试:
--你的声明
declare @text varchar(max)
set @text = N'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queryEE xmlns="http://xx.gob.gcaba.xx/">
<codeEE xmlns="">xxxx</codeEE>
</queryEE>
</s:Body>
</s:Envelope>'
declare @x xml
set @x = cast(@text as xml);
--查询
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS s
,'http://xx.gob.gcaba.xx/' AS innerDflt)
select @x.value('(/s:Envelope/s:Body/innerDflt:queryEE/codeEE/text())[1]','nvarchar(100)');
一些背景:
你的 XML 看着命名空间有点奇怪...如果构造在你的控制之下,那么值得从这里开始。
有一个命名空间 s:
来定义 <Envelope>
和 <Body>
。到目前为止还不错,但是元素 <queryEE>
定义了一个 默认命名空间 (无前缀!),而嵌入的 <codeEE>
定义了另一个(但为空!)默认命名空间。我很确定,这个空命名空间是通过将 XML 组合在一起在查询中创建的...
默认命名空间告诉引擎,所有没有特定前缀的节点都生活在[=48]中=] 这个命名空间。所以我们必须解决这个问题。
我的代码使用 WITH XMLNAMESPACES
声明出现在 XML 中的所有命名空间。与原来的 XML 不同,我为第一个默认命名空间定义了一个前缀 (innerDflt
)。这意味着,我们可以解决 <innerDflt:queryEE>
。嵌入式元素不需要命名空间。它位于一个空的默认(=> 无)命名空间中。
说了这么多,我只想指出,您也可以使用通配符:
select @x.value('(/*:Envelope/*:Body/*:queryEE/*:codeEE/text())[1]','nvarchar(100)')
您甚至可以使用深度搜索
select @x.value('(//*:codeEE/text())[1]','nvarchar(100)')
但一般的建议是:尽可能具体。
我正在尝试解析以下 xml 以获取 s:Body 标记之后的第一个标记(在本例中我正在寻找字符串 queryEE
,在其他情况下具有相同 Envelope/Body 结构的消息会有所不同)
我开始玩这样的东西:
declare @text varchar(max)
set @text = N'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queryEE xmlns="http://xx.gob.gcaba.xx/">
<codeEE xmlns="">xxxx</codeEE>
</queryEE>
</s:Body>
</s:Envelope>'
declare @x xml
set @x = cast(@text as xml)
select @x.query('/s:Envelope')
但我收到错误消息:
Msg 2229, Level 16, State 1, Line 16
XQuery [query()]: The name "s" does not denote a namespace.
好像我在命名空间方面遇到了问题
当我尝试 select @x.query('/Envelope')
时,我根本没有得到任何结果
感谢我从@shnugo 那里得到的答案,我终于可以用以下方法解决它:
select @x.value('local-name((/*:Envelope/*:Body/*)[1])','nvarchar(100)')
在使用 xquery for xml 和命名空间时再次声明您的命名空间。
declare @text varchar(max)
set @text = N'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queryEE xmlns="http://xx.gob.gcaba.xx/">
<codeEE xmlns="">xxxx</codeEE>
</queryEE>
</s:Body>
</s:Envelope>'
declare @x xml
set @x = cast(@text as xml)
select @x.query('declare default element namespace "http://schemas.xmlsoap.org/soap/envelope/";
/Envelope')
这样试试:
--你的声明
declare @text varchar(max)
set @text = N'
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<queryEE xmlns="http://xx.gob.gcaba.xx/">
<codeEE xmlns="">xxxx</codeEE>
</queryEE>
</s:Body>
</s:Envelope>'
declare @x xml
set @x = cast(@text as xml);
--查询
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS s
,'http://xx.gob.gcaba.xx/' AS innerDflt)
select @x.value('(/s:Envelope/s:Body/innerDflt:queryEE/codeEE/text())[1]','nvarchar(100)');
一些背景:
你的 XML 看着命名空间有点奇怪...如果构造在你的控制之下,那么值得从这里开始。
有一个命名空间 s:
来定义 <Envelope>
和 <Body>
。到目前为止还不错,但是元素 <queryEE>
定义了一个 默认命名空间 (无前缀!),而嵌入的 <codeEE>
定义了另一个(但为空!)默认命名空间。我很确定,这个空命名空间是通过将 XML 组合在一起在查询中创建的...
默认命名空间告诉引擎,所有没有特定前缀的节点都生活在[=48]中=] 这个命名空间。所以我们必须解决这个问题。
我的代码使用 WITH XMLNAMESPACES
声明出现在 XML 中的所有命名空间。与原来的 XML 不同,我为第一个默认命名空间定义了一个前缀 (innerDflt
)。这意味着,我们可以解决 <innerDflt:queryEE>
。嵌入式元素不需要命名空间。它位于一个空的默认(=> 无)命名空间中。
说了这么多,我只想指出,您也可以使用通配符:
select @x.value('(/*:Envelope/*:Body/*:queryEE/*:codeEE/text())[1]','nvarchar(100)')
您甚至可以使用深度搜索
select @x.value('(//*:codeEE/text())[1]','nvarchar(100)')
但一般的建议是:尽可能具体。