通常迭代XML中的实体的方法?

时间:2013-05-10 21:37:35

标签: sql-server xml sql-server-2008 tsql

在T-SQL中是否有通用的方法来迭代xml变量并依次为每个实体获取 xml

DECLARE @xml xml = 
'<Entities>
<Entity key="4" attrib1="abc" attrib2="def" />
<Entity key="18" attrib1="ghi" attrib2="jkl" />
<Entity key="938" attrib1="mno" />
</Entities>'

例如,在上面的XML中,有三个实体实例。我依次想要每个XML的XML。我可以用硬编码的方式做到这一点,例如

SELECT @entityxml = @xml.query('/Entities/Entity[1]')

将返回

    <Entity key="4" attrib1="abc" attrib2="def" />

然后我可以将其更改为[2]以获得下一个,依此类推。

但是,根据BOL和实验,@ xml.query的参数必须是字符串文字。换句话说,变量不能用作参数,用[1],[2]等构建它,然后得到许多实体。看起来我们对查询进行了硬编码,这会产生一些丑陋的代码。

我知道可以使用其他方法将xml中的数据放入表中,然后遍历表中的行。我特别询问获取XML本身,即获得上述@ xml.query的等价物,但能够在不必对数组值进行硬编码的情况下这样做。

谢谢!

3 个答案:

答案 0 :(得分:3)

您可以使用position()根据索引选择元素:

DECLARE @xml xml = 
'<Entities>
<Entity key="4" attrib1="abc" attrib2="def" />
<Entity key="18" attrib1="ghi" attrib2="jkl" />
<Entity key="938" attrib1="mno" />
</Entities>'

declare @i int;
set @i = 2;

select @xml.query('Entities/Entity[position()=sql:variable("@i")]');

答案 1 :(得分:1)

问题:

  

例如,在上面的XML中,有三个实体实例。一世   希望依次为每个XML提供XML。

解决方案:

DECLARE @xml xml = 
'<Entities>
<Entity key="4" attrib1="abc" attrib2="def" />
<Entity key="18" attrib1="ghi" attrib2="jkl" />
<Entity key="938" attrib1="mno" />
</Entities>'

SELECT  a.XmlCol.query('.') AS XmlFragment
FROM    @xml.nodes('/Entities/Entity') AS a(XmlCol);

结果:

XmlFragment
------------------------------------------------
<Entity key="4" attrib1="abc" attrib2="def" />
<Entity key="18" attrib1="ghi" attrib2="jkl" />
<Entity key="938" attrib1="mno" />              

演示:

SqlFiddle script

答案 2 :(得分:0)

这样的事情可以解决问题:

DECLARE @xml xml = 
'<Entities>
<Entity key="4" attrib1="abc" attrib2="def" />
<Entity key="18" attrib1="ghi" attrib2="jkl" />
<Entity key="938" attrib1="mno" />
</Entities>';

SELECT @xml.query('
for $i in //Entity
return
<Entity>
    { $i/@key }
    { $i/@attrib1 }
    { $i/@attrib2 }
</Entity>
');