SQL 查询到带有标签属性的 XML
Posted
技术标签:
【中文标题】SQL 查询到带有标签属性的 XML【英文标题】:SQL Query to XML with tag attributes 【发布时间】:2019-11-13 21:09:30 【问题描述】:有一张桌子:
CREATE TABLE temp
(ID int, name varchar(50));
INSERT INTO temp
([ID], [name])
VALUES
(1, 'Value 1'),
(2, 'Value 2');
需要返回以下结果的 SQL 查询:
<root>
<row>
<param name="first">1</param>
<param name="second">Value 1</param>
</row>
<row>
<param name="first">2</param>
<param name="second">Value 2</param>
</row>
</root>
估计的查询是:
SELECT
[ID] as [param/@name['first']],
[name] as [param/@name['second']]
FROM
temp
for xml path('row'), root('root')
请更正查询以使其正常工作。
【问题讨论】:
第二个<row>
片段与第一个<row>
片段完全不同。你确定吗?
@YitzhakKhabinsky 谢谢!已更正
如果建议的解决方案对您有效,请将其标记为正确(绿色检查图像)。
【参考方案1】:
XQuery FLWOR 表达式让您可以完全控制 XML 的形状。看看吧:
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT PRIMARY KEY, [name] varchar(50));
INSERT INTO @tbl (id, [name])
VALUES (1, 'Value 1')
, (2, 'Value 2');
-- DDL and sample data population, end
;WITH rs(xml_data) AS
(
SELECT *
FROM @tbl
FOR XML PATH('row'), TYPE, ROOT('root')
)
SELECT xml_data.query('<root>
for $r in /root/row
return
<row>
<param name="first">data($r/id/text())</param>
<param name="second">data($r/name/text())</param>
</row>
</root>') AS xml_output
FROM rs;
输出
<root>
<row>
<param name="first">1</param>
<param name="second">Value 1</param>
</row>
<row>
<param name="first">2</param>
<param name="second">Value 2</param>
</row>
</root>
【讨论】:
正是需要的!非常感谢! Yitzhak,我想,这可以更简单一点...我只是自己放了一个答案...【参考方案2】:最简单的方法可能是这样的:
SELECT 'first' as [param/@name]
,ID as [param]
,''
,'second' as [param/@name]
,[name] as [param]
FROM temp t
FOR XML PATH('row'), root('root');
简而言之:
引擎在列下工作并找到
我们必须打开一个<root>
我们必须为集合的每一行打开一个<row>
好的,第一列是新元素<param>
,我们要打开它。
现在必须将值(“first”)写入属性@name
。
下一个值(ID
)也住在<param>
,它仍然是开放的。将其添加为 text()
节点。
那么下一栏是 - 嗯 - 空的???但是...首先我们必须关闭打开的<param>
...
好的,下一列看起来更好。有一个元素<param>
...好了,最后一个关闭了,我们要开一个新的!
等等……
这也适用于路径片段:
SELECT 'first' as [param/onemore/@name]
,ID as [param/onemore]
,'' AS [param]
,'second' as [param/onemore/@name]
,[name] as [param/onemore]
FROM temp t
FOR XML PATH('row'), root('root');
结果
<root>
<row>
<param>
<onemore name="first">1</onemore>
<onemore name="second">Value 1</onemore>
</param>
</row>
<row>
<param>
<onemore name="first">2</onemore>
<onemore name="second">Value 2</onemore>
</param>
</row>
</root>
在这种情况下,我们会重新打开 <onemore>
,但我们会留在打开的 <param>
内。
【讨论】:
奇怪,我从你的答案开始尝试了相同的查询,但它没有工作......所以我想出了子查询。 :) 很好的答案,我这边+1!感谢您的详细解释。【参考方案3】:您可以通过子查询实现此目的:
SELECT 'first' as [param/@name],
ID as [param],
(SELECT 'second' as [param/@name],
name as [param]
FROM temp t1 WHERE t1.ID = t.ID
FOR XML PATH(''), TYPE )
FROM temp t
FOR XML PATH('row'), root('root')
输出:
<root>
<row>
<param name="first">1</param>
<param name="second">Value 1</param>
</row>
<row>
<param name="first">2</param>
<param name="second">Value 2</param>
</row>
</root>
【讨论】:
好答案,我这边+1!有第二个解决方案总是很好。 这个可以更简单,我只是放了一个答案,可能你会感兴趣...以上是关于SQL 查询到带有标签属性的 XML的主要内容,如果未能解决你的问题,请参考以下文章
Python通过lxml库遍历xml通过xpath查询(标签,属性名称,属性值,标签对属性)