我正在尝试从XML数据中获取特定的节点,但我终生无法使其正常工作。我在变量和表中有以下XML(两者中的数据相同):
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<HCNSearchResponse xmlns="http://testurl.com/">
<HCNSearchResult>
<HCNLookupResult>
<MsgID>test1</MsgID>
<Results>
<DemographicDetails>
<Title>Ms</Title>
<Forename1>F1 test</Forename1>
<Forename2 />
<Forename3>F3 test</Forename3>
<Sex>F</Sex>
<DateOfBirth>01/01/2000</DateOfBirth>
<Surname>test1</Surname>
</DemographicDetails>
<DemographicDetails>
<Title>Mr</Title>
<Forename1>F1 test</Forename1>
<Forename2 />
<Forename3></Forename3>
<Sex>M</Sex>
<DateOfBirth>01/01/2000</DateOfBirth>
<Surname>test2</Surname>
</DemographicDetails>
</Results>
</HCNLookupResult>
</HCNSearchResult>
</HCNSearchResponse>
</soap:Body>
</soap:Envelope>
我试图仅从中提取“结果”节点,但我无法使其正常工作,我已经尝试了所有这些方法:
SELECT @XMLResult.query('declare namespace
ns="http://testurl.com/";
/ns:HCNSearchResponse/ns:HCNSearchResult/ns:HCNLookupResult/ns:Results')
SELECT @XMLResult.query('/HCNSearchResponse/HCNSearchResult/HCNLookupResult/Results')
SELECT T.N.query('.')
FROM @XMLResult.nodes('/root/Body/Envelope/HCNSearchResponse/HCNSearchResult/HCNLookupResult/Results') as T(N)
SELECT x.*, y.c.query('.')
FROM #xml x
CROSS APPLY x.resultsXML.nodes('/HCNSearchResponse/HCNSearchResult/HCNLookupResult/Results') y(c)
这些都没有完成!这些语句的select语句仅返回空结果。我有一个名为#XML的表,其中有一行,其中XML存储在名为“ resultsXML”的列中,而相同的数据存储在名为@XMLResult的变量中。有人可以帮助我吗?
如果有什么不同,这就是我在xml表中填充该列的方式:
INSERT #XML ( resultsXML )
EXEC sp_OAGetProperty @Obj, 'responseXML.XML'
答案 0 :(得分:3)
您与第一个查询非常接近,但是必须声明所有使用的名称空间。您忘了声明肥皂的名称空间。请参阅下面的工作查询。
makemigrations
答案 1 :(得分:2)
有一个正确的答案,简单奶酪和一个完整的答案:
您的XML:
DECLARE @XMLResult XML=
N'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<HCNSearchResponse xmlns="http://testurl.com/">
<HCNSearchResult>
<HCNLookupResult>
<MsgID>test1</MsgID>
<Results>
<DemographicDetails>
<Title>Ms</Title>
<Forename1>F1 test</Forename1>
<Forename2 />
<Forename3>F3 test</Forename3>
<Sex>F</Sex>
<DateOfBirth>01/01/2000</DateOfBirth>
<Surname>test1</Surname>
</DemographicDetails>
<DemographicDetails>
<Title>Mr</Title>
<Forename1>F1 test</Forename1>
<Forename2 />
<Forename3></Forename3>
<Sex>M</Sex>
<DateOfBirth>01/01/2000</DateOfBirth>
<Surname>test2</Surname>
</DemographicDetails>
</Results>
</HCNLookupResult>
</HCNSearchResult>
</HCNSearchResponse>
</soap:Body>
</soap:Envelope>';
-正确的答案已经由@bdebaere提供。如果要使用它,请在此处设置接受度(但是您当然可以赞成;-))。
-但是您可以使用一个名称空间声明来明确说明所有内容:
-优点:如果使用了几次对XML方法的调用,则必须一遍又一遍地重复声明...
WITH XMLNAMESPACES(DEFAULT 'http://testurl.com/'
,'http://schemas.xmlsoap.org/soap/envelope/' AS [soap])
SELECT @XMLResult.query('/soap:Envelope/soap:Body/HCNSearchResponse/HCNSearchResult/HCNLookupResult/Results');
-轻松奶酪方法使用深度搜索和名称空间通配符
-一般建议是:尽可能具体,但有时懒惰者会赢...
SELECT @XMLResult.query('//*:Results')
-完全确定的答案是这样:
WITH XMLNAMESPACES(DEFAULT 'http://testurl.com/'
,'http://schemas.xmlsoap.org/soap/envelope/' AS [soap])
SELECT dd.value('(Title/text())[1]','nvarchar(max)') AS Title
,dd.value('(Forename1/text())[1]','nvarchar(max)') AS Forename1
,dd.value('(Forename2/text())[1]','nvarchar(max)') AS Forename2
,dd.value('(Forename3/text())[1]','nvarchar(max)') AS Forename3
,dd.value('(Sex/text())[1]','nvarchar(1)') AS Sex
,dd.value('(DateOfBirth/text())[1]','nvarchar(max)') AS DateOfBirth --Hint: don't use 'datetime' here. Rather pull this data as string and use CONVERT with the appropriate style hint
,dd.value('(Surname/text())[1]','nvarchar(max)') AS Surname
FROM @XMLResult.nodes('/soap:Envelope/soap:Body/HCNSearchResponse/HCNSearchResult/HCNLookupResult/Results/DemographicDetails') A(dd);
结果
+-------+-----------+-----------+-----------+-----+-------------+---------+
| Title | Forename1 | Forename2 | Forename3 | Sex | DateOfBirth | Surname |
+-------+-----------+-----------+-----------+-----+-------------+---------+
| Ms | F1 test | NULL | F3 test | F | 01/01/2000 | test1 |
+-------+-----------+-----------+-----------+-----+-------------+---------+
| Mr | F1 test | NULL | NULL | M | 01/01/2000 | test2 |
+-------+-----------+-----------+-----------+-----+-------------+---------+