我想使用SQL查询来解析XML。下面是查询和XML。请在下面找到当前结果和预期结果的屏幕截图。它仅从嵌套节点获取一个值。请建议
DECLARE @xml XML =
'<FileGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FileGroup>
<FileName>Test1</FileName>
<Files>
<File>
<FilePath>\\Server\Test1</FilePath>
<FileGUID>3006989A-725E-40E8-BAF7-A094CB710AC3</FileGUID>
<DependentOnFileNames></DependentOnFileNames>
</File>
<File>
<FilePath>\\Server\Test2</FilePath>
<FileGUID>A584CE87-CC76-484E-ACE4-53C6CAD27B7F</FileGUID>
<DependentOnFileNames></DependentOnFileNames>
</File>
<File>
<FilePath>\\Server\Test3</FilePath>
<FileGUID>727A6BBE-E820-4431-9958-93D0863F65B8</FileGUID>
<Comments></Comments>
<DependentOnFileNames>
<FileGUID>3006989A-725E-40E8-BAF7-A094CB710AC3</FileGUID>
<FileGUID>A584CE87-CC76-484E-ACE4-53C6CAD27B7F</FileGUID>
</DependentOnFileNames>
</File>
</Files>
</FileGroup>
<FileGroup>
<FileName>Test2</FileName>
<Files>
<File>
<FilePath>\\Server\Test4</FilePath>
<FileGUID>EA422762-58CD-423D-92D4-1DC18A312F48</FileGUID>
<DependentOnFileNames></DependentOnFileNames>
</File>
</Files>
</FileGroup>
</FileGroups>'
SELECT
FileGroup.value('FileName[1]', 'VARCHAR(1000)') FileName,
tbl1.Files.value('FilePath[1]', 'VARCHAR(1000)') FilePath,
tbl2.DependentOnFileNames.value('FileGUID[1]', 'UNIQUEIDENTIFIER') DependentFileGUID
FROM @xml.nodes('/FileGroups/FileGroup') tbl(FileGroup)
CROSS APPLY tbl.FileGroup.nodes('Files/File') tbl1(Files)
CROSS APPLY tbl1.Files.nodes('DependentOnFileNames') tbl2(DependentOnFileNames)
答案 0 :(得分:1)
最后一行有2个问题:(1)应该是OUTER APPLY
,因为文件可能没有依赖关系;(2)您需要更深入一层,进入DependentOnFileNames/FileGUID
DependentOnFileNames
中的。应该是:
OUTER APPLY tbl1.Files.nodes('DependentOnFileNames/FileGUID') tbl2(DependentOnFileNames)
然后相应地修改您的SELECT
子句:
tbl2.DependentOnFileNames.value('.', 'UNIQUEIDENTIFIER') DependentFileGUID
对于将来的Google员工,在SQL Server中处理XML的一些技巧:
nodes()
在XML级别扩展嵌套元素value()
获取XML节点的值。 value(...)
中的选择器始终返回值数组,即使它是1的数组也是如此。您只能从该数组中选择1个元素。元素索引从1开始。例外是value(.)
,它返回单例。CROSS APPLY / OUTER APPLY
在SQL级别上扩展nest元素。它们的行为类似于INNER JOIN / LEFT JOIN
,只是不需要加入条件。T1.[FileGroup].query('.')
子句中添加类似SELECT
的内容,并探索XML结构。代码:
SELECT
T1.[FileGroup].value('FileName[1]', 'varchar(30)') AS FileName
, T2.[File].value('FilePath[1]', 'varchar(500)') AS FilePath
, T2.[File].value('FileGUID[1]', 'UNIQUEIDENTIFIER') AS FileGUID
, T3.DependentFileGUID.value('.', 'UNIQUEIDENTIFIER') AS DependentFileGUID
FROM
@xml.nodes('FileGroups/FileGroup') T1([FileGroup])
CROSS APPLY T1.[FileGroup].nodes('Files/File') T2([File])
OUTER APPLY T2.[File].nodes('DependentOnFileNames/FileGUID') T3(DependentFileGUID)