如何将XML值中的两个子节点解析为SQL?

时间:2012-08-16 14:36:08

标签: sql xml sql-server-2008 xml-parsing nodes

我有以下XML:

<xmlRoot>
  <DomainName>sample.com</DomainName>
  <UserCountsByTemplate>
    <KeyValueOfstringint>
      <Key>default</d2p1:Key>
      <Value>20</d2p1:Value>
    </KeyValueOfstringint>
    <KeyValueOfstringint>
      <Key>basic</d2p1:Key>
      <Value>66</d2p1:Value>
    </KeyValueOfstringint>
  </UserCountsByTemplate>
</xmlRoot>

我试图像这样返回两行:

Domain      TemplateName  TemplateCount
----------  ------------  -------------
sample.com  default       20
sample.com  basic         66

我尝试了以下内容:

DECLARE @info XML
SELECT @info = '<xmlRoot><DomainName>sample.com</DomainName><UserCountsByTemplate><KeyValueOfstringint><Key>default</Key><Value>20</Value></KeyValueOfstringint><KeyValueOfstringint><Key>basic</Key><Value>66</Value></KeyValueOfstringint></UserCountsByTemplate></xmlRoot>'
SELECT 
      row.value('DomainName[1]','NVARCHAR(255)') AS [DomainName]
    , row2.value('.','NVARCHAR(255)') AS [TemplateName]
    , row3.value('.','INT') AS [TemplateCount]
FROM @info.nodes('/xmlRoot[1]') T1(row)
CROSS APPLY @info.nodes('/xmlRoot/UserCountsByTemplate/KeyValueOfstringint/Key') T2(row2)
CROSS APPLY @info.nodes('/xmlRoot/UserCountsByTemplate/KeyValueOfstringint/Value') T3(row3)

但是得到以下结果:

Domain      TemplateName  TemplateCount
----------  ------------  -------------
sample.com  default       20
sample.com  basic         20
sample.com  default       66
sample.com  basic         66

关于我在哪里出错的任何想法?

1 个答案:

答案 0 :(得分:1)

您没有将您对Key的访问权限与对价值的访问权限相关联 - 因此您可以有效地在所有键和所有值之间产生交叉连接。

DECLARE @info XML
SELECT @info = '<xmlRoot><DomainName>sample.com</DomainName><UserCountsByTemplate><KeyValueOfstringint><Key>default</Key><Value>20</Value></KeyValueOfstringint><KeyValueOfstringint><Key>basic</Key><Value>66</Value></KeyValueOfstringint></UserCountsByTemplate></xmlRoot>'
SELECT 
      row.value('DomainName[1]','NVARCHAR(255)') AS [DomainName]
    , row2.value('Key[1]','NVARCHAR(255)') AS [TemplateName]
    , row2.value('Value[1]','INT') AS [TemplateCount]
FROM @info.nodes('/xmlRoot[1]') T1(row)
CROSS APPLY @info.nodes('/xmlRoot/UserCountsByTemplate/KeyValueOfstringint') T2(row2)

相反,我正在提取KeyValueOfstringInt个节点,然后访问value()调用中的不同元素。但是两个value()调用都在相同的节点上运行(对于每一行)。