问题描述
在使用xml.value遍历XML时,我无法使用索引进行迭代。 在下面的代码中,您可以看到我正在尝试迭代xml并尝试在Detail节点下打印Value。但是,如果我对索引进行硬编码,则可以很好地工作,但是我需要从while循环增量中传递索引。我不确定如何传递总是失败的索引
DECLARE @myXml XML = '
<EmployeeConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema">
<Employee>
<Detail Id="100" Name="John">
<Type>Permanent</Type>
<Value>U2tpbGw=</Value>
</Detail>
</Employee>
<Employee>
<Detail Id="200" Name="Rachel">
<Type>Contract</Type>
<Value>RXhwZXJpZW5jZQ==</Value>
</Detail>
</Employee>
<Employee>
<Detail Id="300" Name="Danny">
<Type>Permanent</Type>
<Value>U2tpbGw=</Value>
</Detail>
</Employee>
</EmployeeConfiguration>'
SELECT @myXml
DECLARE @count INT,@i INT;
DECLARE @Value varchar(max);
SELECT @count = @myXml.query('<e>
{ count(/EmployeeConfiguration/Employee/Detail) }
</e>').value('e[1]','int')
SELECT @count -- Returns count as 3
SET @i=1
WHILE @i < = @count
BEGIN
-- SELECT @Value = @myXml.value('(/EmployeeConfiguration/Employee/Detail/Value)[2]','nvarchar(max)') -- This code works if Hardcode the index and returns correct value (RXhwZXJpZW5jZQ==) in this case
-- This does not work and I get this error
-- Msg 2389,Level 16,State 1,Line 39
-- XQuery [value()]: 'value()' requires a singleton (or empty sequence),-- found operand of type 'xdt:untypedAtomic *'
SELECT @Value = @myXml.value('(/EmployeeConfiguration/Employee/Detail/Value) [@i]','nvarchar(max)')
-- This is also not working
SELECT @Value = @myXml.value('(/EmployeeConfiguration/Employee/Detail/Value)[sql:variable(@i)]','nvarchar(max)')
SELECT @Value
SET @i = @i + 1
END
解决方法
DECLARE @myXml XML = '
<EmployeeConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema">
<Employee>
<Detail Id="100" Name="John">
<Type>Permanent</Type>
<Value>U2tpbGw=</Value>
</Detail>
</Employee>
<Employee>
<Detail Id="200" Name="Rachel">
<Type>Contract</Type>
<Value>RXhwZXJpZW5jZQ==</Value>
</Detail>
</Employee>
<Employee>
<Detail Id="300" Name="Danny">
<Type>Permanent</Type>
<Value>U2tpbGw=</Value>
</Detail>
</Employee>
</EmployeeConfiguration>'
declare @i int = 2;
--RXhwZXJpZW5jZQ==
SELECT @myXml.value('(EmployeeConfiguration/Employee/Detail/Value)[sql:variable("@i")][1]','nvarchar(max)');
set @i = 3;
--U2tpbGw=
SELECT @myXml.value('(EmployeeConfiguration/Employee/Detail/Value)[sql:variable("@i")][1]','nvarchar(max)');