如何使用 TSQL XQUERY 粉碎 XML
How to shred XML with TSQL XQUERY
我正在努力撕碎以下 XML。我正在使用 Azure SQL 数据库。
这是我的示例数据和代码尝试。
DROP TABLE IF EXISTS #t ;
CREATE TABLE #t (XMLResult XML) ;
INSERT INTO #t (XMLResult)
VALUES ( '<testsuites>
<testsuite id="1" name="Verify" tests="1" errors="0" failures="1" timestamp="2021-12-08" time="0.000" hostname="" package="tSQLt">
<properties />
<testcase classname="Verify" name="Verify [Feature].[measure] format" time="0.000">
<failure message="Format incorrectly set." type="Failure" />
</testcase>
</testsuite>
</testsuites>
') ;
SELECT T.* ,
TS.H.value('name[1]', 'varchar(255)') AS [Test Method] ,
TS.H.value('tests[1]', 'int') AS [Tests] ,
TS.H.value('failures[1]', 'int') AS [Failures] ,
TC.H.value('name[1]', 'VARCHAR(255)') AS [TestCase] ,
TF.H.value('message[1]', 'VARCHAR(255)') AS [Failure Message]
FROM #t T
CROSS APPLY T.XMLResult.nodes('/testsuites/testsuite') AS TS(H)
CROSS APPLY T.XMLResult.nodes('/testsuites/testsuite/testcase') AS TC(H)
CROSS APPLY T.XMLResult.nodes('/testsuites/testsuite/testcase/failure') AS TF(H)
;
当前输出
我哪里错了?
如评论中所述,您有 XML 属性 ,而不是您要检索的 值 。所以你需要用 @
来引用它们
您也使用 .nodes
错误:您应该将每一个都引用到上一个。实际上,您只是将所有节点级别交叉连接在一起。
SELECT --T.* ,
TS.H.value('@name', 'varchar(255)') AS [Test Method] ,
TS.H.value('@tests', 'int') AS [Tests] ,
TS.H.value('@failures', 'int') AS [Failures] ,
TC.H.value('@name', 'VARCHAR(255)') AS [TestCase] ,
TF.H.value('@message', 'VARCHAR(255)') AS [Failure Message]
FROM #t T
CROSS APPLY T.XMLResult.nodes('/testsuites/testsuite') AS TS(H)
CROSS APPLY TS.H.nodes('testcase') AS TC(H)
CROSS APPLY TC.H.nodes('failure') AS TF(H)
;
请注意,如果您直接引用当前节点(而不是子节点)的属性,则不需要 [1]
谓词
我正在努力撕碎以下 XML。我正在使用 Azure SQL 数据库。
这是我的示例数据和代码尝试。
DROP TABLE IF EXISTS #t ;
CREATE TABLE #t (XMLResult XML) ;
INSERT INTO #t (XMLResult)
VALUES ( '<testsuites>
<testsuite id="1" name="Verify" tests="1" errors="0" failures="1" timestamp="2021-12-08" time="0.000" hostname="" package="tSQLt">
<properties />
<testcase classname="Verify" name="Verify [Feature].[measure] format" time="0.000">
<failure message="Format incorrectly set." type="Failure" />
</testcase>
</testsuite>
</testsuites>
') ;
SELECT T.* ,
TS.H.value('name[1]', 'varchar(255)') AS [Test Method] ,
TS.H.value('tests[1]', 'int') AS [Tests] ,
TS.H.value('failures[1]', 'int') AS [Failures] ,
TC.H.value('name[1]', 'VARCHAR(255)') AS [TestCase] ,
TF.H.value('message[1]', 'VARCHAR(255)') AS [Failure Message]
FROM #t T
CROSS APPLY T.XMLResult.nodes('/testsuites/testsuite') AS TS(H)
CROSS APPLY T.XMLResult.nodes('/testsuites/testsuite/testcase') AS TC(H)
CROSS APPLY T.XMLResult.nodes('/testsuites/testsuite/testcase/failure') AS TF(H)
;
当前输出
我哪里错了?
如评论中所述,您有 XML 属性 ,而不是您要检索的 值 。所以你需要用 @
您也使用 .nodes
错误:您应该将每一个都引用到上一个。实际上,您只是将所有节点级别交叉连接在一起。
SELECT --T.* ,
TS.H.value('@name', 'varchar(255)') AS [Test Method] ,
TS.H.value('@tests', 'int') AS [Tests] ,
TS.H.value('@failures', 'int') AS [Failures] ,
TC.H.value('@name', 'VARCHAR(255)') AS [TestCase] ,
TF.H.value('@message', 'VARCHAR(255)') AS [Failure Message]
FROM #t T
CROSS APPLY T.XMLResult.nodes('/testsuites/testsuite') AS TS(H)
CROSS APPLY TS.H.nodes('testcase') AS TC(H)
CROSS APPLY TC.H.nodes('failure') AS TF(H)
;
请注意,如果您直接引用当前节点(而不是子节点)的属性,则不需要 [1]
谓词