How to parse SOAP XML in SQL Server and show as table - sql

I need to parser a SOAP xml in SQL Server and convert it to table
<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>
<ExecCommandResponse xmlns="http://tempuri.org/">
<ExecCommandResult>
<Result xmlns="">
<row>
<LOT>VERL5B3002PL</LOT>
<ID>115</ID>
<WH>710</WH>
<STPL>12</STPL>
</row>
<row>
<LOT>VERL68804EVN</LOT>
<ID>3716</ID>
<WH>771</WH>
<STPL>6</STPL>
</row>
</Result>
</ExecCommandResult>
</ExecCommandResponse>
</soap:Body>
</soap:Envelope>
I need to parser a SOAP xml in sql server and convert it to table
LOT | ID | WH | STPL
VERL68804EVN | 3716 | 771 | 6

Use the up-to-date functions to query XML.
Your XML is not very clean looking on the namespaces. There are two default namespaces, one of them empty... Therefore I would avoid (mask) them entirely.
DECLARE #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>
<ExecCommandResponse xmlns="http://tempuri.org/">
<ExecCommandResult>
<Result xmlns="">
<row>
<LOT>VERL5B3002PL</LOT>
<ID>115</ID>
<WH>710</WH>
<STPL>12</STPL>
</row>
<row>
<LOT>VERL68804EVN</LOT>
<ID>3716</ID>
<WH>771</WH>
<STPL>6</STPL>
</row>
</Result>
</ExecCommandResult>
</ExecCommandResponse>
</soap:Body>
</soap:Envelope>';
SELECT r.value('LOT[1]','varchar(max)') AS LOT
,r.value('ID[1]','int') AS ID
,r.value('WH[1]','int') AS WH
,r.value('STPL[1]','int') AS STPL
FROM #xml.nodes('/*:Envelope/*:Body/*:ExecCommandResponse/*:ExecCommandResult/*:Result/*:row') AS A(r)
--or even simpler (would even work without the *:):
SELECT r.value('LOT[1]','varchar(max)') AS LOT
,r.value('ID[1]','int') AS ID
,r.value('WH[1]','int') AS WH
,r.value('STPL[1]','int') AS STPL
FROM #xml.nodes('//*:row') AS A(r)
In general I'd say: Be as specific as possible, therefore rather suggest the first...

Try Below. See if it works.
declare #xmldata 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>
<ExecCommandResponse>
<ExecCommandResult>
<Result xmlns="">
<row>
<LOT>VERL5B3002PL</LOT>
<ID>115</ID>
<WH>710</WH>
<STPL>12</STPL>
</row>
<row>
<LOT>VERL68804EVN</LOT>
<ID>3716</ID>
<WH>771</WH>
<STPL>6</STPL>
</row>
</Result>
</ExecCommandResult>
</ExecCommandResponse>
</soap:Body>
</soap:Envelope>'
declare #readdoc as INT
EXEC sp_xml_preparedocument #readdoc OUTPUT, #xmldata , '<root 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" />'
select LOT,ID,WH,STPL
from OPENXML(#readdoc,'soap:Envelope/soap:Body/ExecCommandResponse/ExecCommandResult/Result/row')
with
(
LOT [varchar](50) 'LOT',
ID [varchar](50) 'ID',
WH [varchar](50) 'WH',
STPL [varchar](50) 'STPL'
)
EXEC sp_xml_removedocument #readdoc
GO
Below is the output.

Related

How to parse SOAP xml in sql server and show to table format

the webservice returned SOAP xml result, i would like to change the format to table in SQL server
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<MemberInformationResponse xmlns="http://www.ucr.com.hk">
<MemberInformationResult>
<Code>0</Code>
<Description>Get Member Info Success </Description>
<MemberCode>9997</MemberCode>
<MemberCardCode>9997</MemberCardCode>
<MemberTypeCode>GOLD2020</MemberTypeCode>
<MemberTypeName1>Gold Member 2020</MemberTypeName1>
<MemberTypeName2>Gold Member 2020</MemberTypeName2>
<OldMemberTypeCode>SilverLINE</OldMemberTypeCode>
<OldMemberTypeName1>Silver Member(LINE)</OldMemberTypeName1>
<OldMemberTypeName2>Silver Member(LINE)</OldMemberTypeName2>
<LoginID>9997</LoginID>
<Name1>SilverLINE</Name1>
<Name2>SilverLINE</Name2>
<Sex>0</Sex>
<Mobile>99900099</Mobile>
<Email>khso#kabu.com.hk</Email>
<PromotionAlert>1</PromotionAlert>
<YearOfBirth>2001</YearOfBirth>
<MonthOfBirth>01</MonthOfBirth>
<JoinDate>2016/03/01</JoinDate>
<WorkingDistrict />
<LivingDistrict />
<ActivationCode>4516</ActivationCode>
<ReferralMemberCardCode>0151136201</ReferralMemberCardCode>
<Enabled>0</Enabled>
<Point>1005</Point>
<Point1>1005</Point1>
<Point2>0</Point2>
<AccumulatedAmount>16376.8</AccumulatedAmount>
<ExpiryDate>2020/08/31</ExpiryDate>
<ExtendExpiryDate>2021/08/31</ExtendExpiryDate>
<PointRemain>0</PointRemain>
<PointExpiryDate>----/--/--</PointExpiryDate>
</MemberInformationResult>
</MemberInformationResponse>
</soap:Body>
</soap:Envelope>
I tried below script, but no result return.
declare #xmldata xml
SET #xmldata = *put above soap xml*
declare #readdoc as INT
EXEC sp_xml_preparedocument #readdoc OUTPUT, #xmldata , '<root xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />'
select Code, MemberCode
from OPENXML(#readdoc,'soap:Envelope/soap:Body/MemberInformationResponse/MemberInformationResult')
with
(
Code int 'Code',
MemberCode [varchar](50) 'MemberCode'
)
EXEC sp_xml_removedocument #readdoc
GO
How to get output like this :
| Code | MemberCode |
| ---- | ---------- |
| 0 | 9997 |
please help to advise. Thanks.
Not an answer....
I believe it's something to do with MemberInformationResponse being in yet another namespaces
I think the newer way to do this is use the methods of the XML data type
https://learn.microsoft.com/en-us/previous-versions/sql/sql-server-2005/ms190798(v=sql.90)?redirectedfrom=MSDN
Rather than sp_xml_preparedocument etc.
If you want to stick with sp_xml_preparedocument, I suggest you experiment with this. It produces an output and you can iteratively experiment with it.
declare #xmldata VARCHAR(8000)
SET #xmldata = '<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<MemberInformationResponse xmlns="http://www.ucr.com.hk">
<MemberInformationResult>
<Code>0</Code>
<Description>Get Member Info Success </Description>
<MemberCode>9997</MemberCode>
<MemberCardCode>9997</MemberCardCode>
<MemberTypeCode>GOLD2020</MemberTypeCode>
<MemberTypeName1>Gold Member 2020</MemberTypeName1>
<MemberTypeName2>Gold Member 2020</MemberTypeName2>
<OldMemberTypeCode>SilverLINE</OldMemberTypeCode>
<OldMemberTypeName1>Silver Member(LINE)</OldMemberTypeName1>
<OldMemberTypeName2>Silver Member(LINE)</OldMemberTypeName2>
<LoginID>9997</LoginID>
<Name1>SilverLINE</Name1>
<Name2>SilverLINE</Name2>
<Sex>0</Sex>
<Mobile>99900099</Mobile>
<Email>khso#kabu.com.hk</Email>
<PromotionAlert>1</PromotionAlert>
<YearOfBirth>2001</YearOfBirth>
<MonthOfBirth>01</MonthOfBirth>
<JoinDate>2016/03/01</JoinDate>
<WorkingDistrict />
<LivingDistrict />
<ActivationCode>4516</ActivationCode>
<ReferralMemberCardCode>0151136201</ReferralMemberCardCode>
<Enabled>0</Enabled>
<Point>1005</Point>
<Point1>1005</Point1>
<Point2>0</Point2>
<AccumulatedAmount>16376.8</AccumulatedAmount>
<ExpiryDate>2020/08/31</ExpiryDate>
<ExtendExpiryDate>2021/08/31</ExtendExpiryDate>
<PointRemain>0</PointRemain>
<PointExpiryDate>----/--/--</PointExpiryDate>
</MemberInformationResult>
</MemberInformationResponse>
</soap:Body>
</soap:Envelope>
'
declare #readdoc as INT
EXEC sp_xml_preparedocument #readdoc OUTPUT, #xmldata, '<root xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />'
select *
from OPENXML(#readdoc,'/soap:Envelope/soap:Body')
EXEC sp_xml_removedocument #readdoc
GO

T-sql select xml value

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Teste xmlns="http://google.com">
<Username></Username>
<Password></Password>
<Firma>Blabla</Firma>
</Teste>
</soap:Header>
<soap:Body>
-- Omitted
</soap:Body>
</soap:Envelope>
Having this xml in a column, how to retrieve the Firma value ? What's giving me more trouble is the "soap" namespaces that seem to be ruining my query's
This is what I was experimenting with, but not working as expected since the path is wrong
select ref.col.value('.','varchar(255)')
from my_View tbl
cross apply tbl.XMLColumn.nodes('Envelope/Header/Teste/Firma') as ref(col)
You must use namespaces in your Xquery
create table so_Test (XMLColumn xml)
go
insert so_Test
select '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Teste xmlns="http://google.com">
<Username></Username>
<Password></Password>
<Firma>Blabla</Firma>
</Teste>
</soap:Header>
<soap:Body>
</soap:Body>
</soap:Envelope>'
select XMLColumn.value('
declare namespace soap="http://schemas.xmlsoap.org/soap/envelope/";
declare namespace google="http://google.com";
/soap:Envelope[1]/soap:Header[1]/google:Teste[1]/google:Firma[1]', 'varchar(255)') as Firma from so_test
Result:
Firma
Blabla

SqlServer XQuery always concat two fields

I want to get somedata from one column only from an xml field:
<CDirData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://Fnet.ESB.Schemas.CentroDirectivo.CDirData">
<ProcedureData xmlns="">
<ProcedureId>7001</ProcedureId>
<CentroDirectivo>Subsecretaria</CentroDirectivo>
</ProcedureData>
<SolicitudData xmlns="">
...
with my query
SELECT top 1
[Message].query('//*[local-name()="ProcedureId"]').value('.','nvarchar(max)') as R
from
ManagementCenterQueueHistorical
but allways returns the fields concat
I would need just only the first one
Thanks in advance!
Put your XPath expressin in parenthessis and add [1] to get only first element from the group
DECLARE #x XML = '<CDirData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://Fnet.ESB.Schemas.CentroDirectivo.CDirData">
<ProcedureData xmlns="">
<ProcedureId>7001</ProcedureId>
<CentroDirectivo>Subsecretaria1</CentroDirectivo>
</ProcedureData>
<ProcedureData xmlns="">
<ProcedureId>7002</ProcedureId>
<CentroDirectivo>Subsecretaria2</CentroDirectivo>
</ProcedureData>
<ProcedureData xmlns="">
<ProcedureId>7003</ProcedureId>
<CentroDirectivo>Subsecretaria3</CentroDirectivo>
</ProcedureData>
<ProcedureData xmlns="">
<ProcedureId>7004</ProcedureId>
<CentroDirectivo>Subsecretaria4</CentroDirectivo>
</ProcedureData>
</CDirData>'
SELECT
#x.query('(//*[local-name()="ProcedureId"])[1]').value('.','nvarchar(max)') as R

SQL server XML type

I have an XML type column in SQL server:
<LogMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LogMessageBusinessServiceRequest">
<Application>Services.Business.myapp</Application>
<Time>2013-05-30T15:01:38.932Z</Time>
<Level>Info</Level>
<Message>MultiQuery Biz Request</Message>
<MachineName>Machine1</MachineName>
<ThreadId>16084</ThreadId>
<Callsite>BLAH</Callsite>
<CreatedBy>Machine1\svc_biz_myapp</CreatedBy>
<Context>
<myappExtraInfo xmlns="http://services.somedomain.com/myapp/logging/extraInfo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CallType>MultiProcessQuery</CallType>
<RequestId>r163505508498822282742</RequestId>
<FirmId>160</FirmId>
<PMFirmId>203</PMFirmId>
<SubscriptionId>0</SubscriptionId>
<Token />
<LastClientSvcTimeMs>0</LastClientSvcTimeMs>
<ResultCode>0</ResultCode>
<ResultCodeDescription>OK</ResultCodeDescription>
<ElapsedTimeTotalMs>110</ElapsedTimeTotalMs>
<ElapsedTimeMtMs>110</ElapsedTimeMtMs>
<ElapsedTimeDacMs>109</ElapsedTimeDacMs>
<ElapsedTimePMSSMs>-1</ElapsedTimePMSSMs>
</myappExtraInfo>
</Context>
I want to get the FirmID from there. But I am not able with the following section of my select statement:
select
[Body].value('(/LogMessage/Context/myappExtraInfo/FirmId)[1]', 'varchar(max)') FirmID
What am I doing wrong?
Thanks for your time.
Shiyam
Try this - you need to respect the XML namespace that's defined on your <myappExtraInfo> node (and thus applies to all subnodes, too):
DECLARE #Test TABLE (ID INT NOT NULL, XmlContent XML)
INSERT INTO #Test VALUES(1,
'<LogMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LogMessageBusinessServiceRequest">
<Application>Services.Business.myapp</Application>
<Time>2013-05-30T15:01:38.932Z</Time>
<Level>Info</Level>
<Message>MultiQuery Biz Request</Message>
<MachineName>Machine1</MachineName>
<ThreadId>16084</ThreadId>
<Callsite>BLAH</Callsite>
<CreatedBy>Machine1\svc_biz_myapp</CreatedBy>
<Context>
<myappExtraInfo xmlns="http://services.somedomain.com/myapp/logging/extraInfo" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CallType>MultiProcessQuery</CallType>
<RequestId>r163505508498822282742</RequestId>
<FirmId>160</FirmId>
<PMFirmId>203</PMFirmId>
<SubscriptionId>0</SubscriptionId>
<Token />
<LastClientSvcTimeMs>0</LastClientSvcTimeMs>
<ResultCode>0</ResultCode>
<ResultCodeDescription>OK</ResultCodeDescription>
<ElapsedTimeTotalMs>110</ElapsedTimeTotalMs>
<ElapsedTimeMtMs>110</ElapsedTimeMtMs>
<ElapsedTimeDacMs>109</ElapsedTimeDacMs>
<ElapsedTimePMSSMs>-1</ElapsedTimePMSSMs>
</myappExtraInfo>
</Context>
</LogMessage>')
;WITH XMLNAMESPACES('http://services.somedomain.com/myapp/logging/extraInfo' AS ns)
SELECT
XmlContent.value('(/LogMessage/Context/ns:myappExtraInfo/ns:FirmId)[1]', 'int')
FROM #Test
WHERE ID = 1
This returns the value 160 to me.

How can I select tags from an SQL XML Query?

How can I retrieve the fields within an XML field in MS SQL?
Every query I try does not work as intended whenever I use this XML code:
I want to select the AccNumber value.
<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:Header>
<AuthSoapHd xmlns="https://temp.uri.com/Mngmt/">
<System>System1</System>
</AuthSoapHd>
</soap:Header>
<soap:Body>
<PrintList xmlns="https://temp.uri.com/Mngmt/">
<Account>
<AccNumber xmlns="https://temp.uri.com/Project/Object/Data">990368644</AccNumber>
</Account>
</PrintList>
</soap:Body>
</soap:Envelope>
I tried multiple varations of the following with no sucess
Select [RequestXML].query('/Envelope/Body/PrintList/Account/AccNumber')
FROM [dbo].[Table1]
You're ignoring the XML namespace that is in play - you need to pay attention to that!
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS soap,
'https://temp.uri.com/Project/Object/Data' AS data,
'https://temp.uri.com/Mngmt/' AS mgmt)
SELECT
RequestXML.value('(/soap:Envelope/soap:Body/mgmt:PrintList/mgmt:Account/data:AccNumber)[1]',
'BIGINT') AS 'AccNumber'
FROM
[dbo].[Table1]
That hopefully works!