我有一些(未类型化的)XML 存储在 SQL Server 2005 中,我需要将其转换为规范化结构。当前文档的结构如下所示:
<wrapper>
<parent />
<node />
<node />
<node />
<parent />
<node />
<node />
<node />
<wrapper>
我想把它改成这样:
<wrapper>
<parent>
<node />
<node />
<node />
</parent>
<parent>
<node />
<node />
<node />
</parent>
<wrapper>
如果需要,我可以将 XML 选择为关系结构,问题是没有将父节点和子节点链接在一起的属性,因此在使用基于集合的操作时顺序成为问题。我如何使用 .nodes()/.value()/其他 SQL Server XML API 来转换此数据?转换需要作为批处理 SQL 脚本的一部分运行,因此将其提取到另一种工具/语言中对我来说不是一个合理的选择。
最佳答案
实际上 - 以下代码有效(此处分组可能不是最佳选择,但无论如何):
declare @xml xml = '
<wrapper>
<parent id="1" />
<node id="1" />
<node id="2" />
<node id="3" />
<parent id="2" />
<node id="4" />
<node id="5" />
<node id="6" />
</wrapper>
'
;with px as
(
select row_number() over (order by (select 1)) as RowNumber
,t.v.value('@id', 'int') as Id
,t.v.value('local-name(.)', 'nvarchar(max)') as TagName
from @xml.nodes('//wrapper/*') as t(v)
)
select p.Id as [@id],
(
select n.Id as id
from px n
where n.TagName = 'node'
and n.RowNumber > p.RowNumber
and not exists
(
select null
from px np
where np.TagName = 'parent'
and np.RowNumber > p.RowNumber
and np.RowNumber < n.RowNumber
)
order by n.RowNumber
for xml raw('node'), type
)
from px p
where p.TagName = 'parent'
order by p.RowNumber
for xml path('parent'), root('wrapper')
但我不推荐使用它。看这里:http://msdn.microsoft.com/en-us/library/ms172038%28v=sql.90%29.aspx :
In SQLXML 4.0, document order is not always determined所以我不确定我们是否可以依赖 wrapper 中标签的顺序(上面的代码只是为了好玩而不是为了实际使用)。
关于sql - 使用 SQL Server 2005 XML API 规范化 XML 片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6780968/