我已经看了一眼,但却无法找到能帮我解决问题的答案。 (很可能是因为我的技能很差)
然而,希望有人能够指出我正确的方向。
问题: 我在表中查询了一个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'
然而,这似乎根本没有返回任何行,如果有人能指出我在这里做错了什么,我将非常感激。
提前致谢,
答案 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)