无法使用XMLNAMESPACES搜索特定值

时间:2017-07-14 11:50:04

标签: sql-server sqlxml

我已经看了一眼,但却无法找到能帮我解决问题的答案。 (很可能是因为我的技能很差)

然而,希望有人能够指出我正确的方向。

问题: 我在表中查询了一个XML列,我需要查询返回所有具有特定值的行。

xml列的示例

 <EventD xmlns="http://example1" xmlns:e3q1="http://example2" xmlns:xsi="http://example3" xsi:type="e3q1:Valuechange">
  <e3q1:NewValue>Running</e3q1:NewValue>
  <e3q1:OldValue>Stopped</e3q1:OldValue>
</EventD>

我需要做的是将所有将“NewValue”作为“Running”的行返回

;WITH XMLNAMESPACES ('example2' as e3q1)
select top 100 
Xml.value('(EventD/NewValue)[1]', 'varchar(100)'),

* from Table1
and Xml.value('(EventD/NewValue)[1]', 'varchar(100)') like 'Running'

然而,这似乎根本没有返回任何行,如果有人能指出我在这里做错了什么,我将非常感激。

提前致谢,

2 个答案:

答案 0 :(得分:1)

看起来Jeroen Mostert已经说了所有必要的东西 我只能添加 - 命名空间的名称并不重要,只有uri

declare @xml xml='<EventD xmlns="http://example1" xmlns:e3q1="http://example2" xmlns:xsi="http://example3" xsi:type="e3q1:Valuechange">
  <e3q1:NewValue>Running</e3q1:NewValue>
  <e3q1:OldValue>Stopped</e3q1:OldValue>
  <xsi:test>test</xsi:test>
  <test1>test1</test1>
</EventD>'


;WITH XMLNAMESPACES ('http://example2' as test)  
select
 @xml.query('(*/test:*)') 

的结果进行比较
select
     @xml.query('(*/*)') 

答案 1 :(得分:1)

您确实声明了名称空间e3q1(虽然它错过了http://并且您以后不再使用它...),但您没有声明默认命名空间

DECLARE @tbl TABLE([Xml] XML);
INSERT INTO @tbl VALUES
(
 N'<EventD xmlns="http://example1" xmlns:e3q1="http://example2" xmlns:xsi="http://example3" xsi:type="e3q1:Valuechange">
  <e3q1:NewValue>Running</e3q1:NewValue>
  <e3q1:OldValue>Stopped</e3q1:OldValue>
</EventD>'
);

;WITH XMLNAMESPACES (DEFAULT 'http://example1', 'http://example2' as e3q1)
SELECT [Xml].value('(EventD/e3q1:NewValue)[1]', 'varchar(100)')
from @tbl AS Table1
WHERE Xml.value('(EventD/e3q1:NewValue)[1]', 'varchar(100)') like 'Running';

但这种做法 - 至少我是这么认为 - 不是你真正想要的。我想你正在寻找.nodes()。下一行显示了使用通配符替换名称空间的替代方法。但我建议尽可能具体。

SELECT Only.Running.value('text()[1]', 'varchar(100)')
from @tbl AS Table1
CROSS APPLY Xml.nodes('*:EventD/*:NewValue[text()="Running"]') AS Only(Running)