And*_*y M 14 xml sql-server xquery sql-server-2014
我有一个这样的 XML 值:
<R>
<I>A</I>
<I>B</I>
<I>C</I>
...
</R>
Run Code Online (Sandbox Code Playgroud)
我想连接所有的I
值并返回它们作为单个字符串:ABC...
。
现在我知道我可以分解 XML,将结果聚合回无节点 XML,然后应用于.values('text()[1]', ...)
结果:
SELECT
(
SELECT
n.n.value('text()[1]', 'varchar(50)') AS [text()]
FROM
@MyXml.nodes('/R/I') AS n (n)
FOR XML
PATH (''),
TYPE
).value('text()[1]', 'varchar(50)')
;
Run Code Online (Sandbox Code Playgroud)
但是,我想仅使用 XPath/XQuery 方法来完成所有这些工作,如下所示:
SELECT @MyXml. ? ( ? );
Run Code Online (Sandbox Code Playgroud)
有这样的方法吗?
我在这个方向寻找解决方案的原因是因为我的实际 XML 也包含其他元素,例如:
SELECT
(
SELECT
n.n.value('text()[1]', 'varchar(50)') AS [text()]
FROM
@MyXml.nodes('/R/I') AS n (n)
FOR XML
PATH (''),
TYPE
).value('text()[1]', 'varchar(50)')
;
Run Code Online (Sandbox Code Playgroud)
而且我希望能够将I
值提取为单个字符串,并将J
值提取为单个字符串,而不必为每个值使用笨拙的脚本。
Mik*_*son 11
这可能对你有用:
select @MyXml.value('/R[1]', 'varchar(50)')
Run Code Online (Sandbox Code Playgroud)
它text()
从第一个R
和下面选取所有元素。
如果你只是想要text()
你能做的一切
select @MyXml.value('.', 'varchar(50)')
Run Code Online (Sandbox Code Playgroud)
如果你想的价值观I
和J
单独做到这一点,而不是。
select @MyXml.query('/R/I/text()').value('.', 'varchar(50)'),
@MyXml.query('/R/J/text()').value('.', 'varchar(50)')
Run Code Online (Sandbox Code Playgroud)
根据您的实际 XML 结构,您可以考虑使用这样的循环:
DECLARE @xml XML
SELECT @xml = '<R>
<I>A</I>
<I>B</I>
<I>C</I>
<J>X</J>
<J>Y</J>
<J>Z</J>
</R>'
SELECT
Tbl.Col.query('for $i in I return $i').value('.', 'nvarchar(max)'),
Tbl.Col.query('for $i in J return $i').value('.', 'nvarchar(max)')
FROM @xml.nodes('R') Tbl(Col);
Run Code Online (Sandbox Code Playgroud)
输出这个:
(No column name) | (No column name)
--------------- | ---------------
ABC | XYZ
Run Code Online (Sandbox Code Playgroud)
看到这个小提琴