SqlServer XQuery always concat two fields - sql-server-2012

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

Related

Import field in XML using SQL not working

i've been trying to import the field GivenName in my example XML but for some reason it's not working, i've been using the following SQL query, i think i'm using the correct field and the correct nodes but i'm not 100% sure about the XMLNameSpaces
Thank you very much in advance for your help
This is the example SQL Query i'm using:
DECLARE #xml XML = (SELECT [Xml] FROM ExampleTable)
;WITH XMLNAMESPACES (DEFAULT 'http://www.opentravel.org/OTA/2003/05','http://www.w3.org/2003/05/soap-envelope' )
select FirstName = ProfileInfo.value('Profiles[1]/ProfileInfo[1]/Profile[1]/Customer[1]/PersonName[1]/#GivenName', 'nvarchar(255)')
FROM #xml.nodes('Envelope/Body/OTA_Example/Info/Infos/ResUser') as T1(Profiles)
outer apply T1.Profiles.nodes('ResUser2') as T2(ProfileInfo)
This is the example XML i'm using for the import:
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope">
<soap2:Header xmlns:htng="http://htng.org/1.3/Header/" xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:wss="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:htnga="http://htng.org/PWSWG/2007/02/AsyncHeaders"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap2="http://www.w3.org/2003/05/soap-envelope">
<wsa:Action>Example</wsa:Action>
<wsa:ReplyTo>
<wsa:Address>Example2</wsa:Address>
</wsa:ReplyTo>
<htnga:ReplyTo>
<wsa:Address>Example3</wsa:Address>
</htnga:ReplyTo>
<wsa:MessageID>123</wsa:MessageID>
</soap2:Header>
<Body>
<OTA_Example xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.opentravel.org/OTA/2003/05" Version="5.000" >
<Info>
<Infos CreateDateTime="2021-09-20T06:52:40" CreatorID="User">
<UniqueID Type="1" ID="12341251" />
<ResUser>
<ResUser2 ResGuestRPH="1" PrimaryIndicator="true">
<Profiles>
<ProfileInfo>
<Profile ProfileType="1">
<Customer>
<PersonName>
<NamePrefix>Mr.</NamePrefix>
<GivenName>FirstnameTest</GivenName>
<Surname>LastnameTest</Surname>
</PersonName>
</Customer>
</Profile>
</ProfileInfo>
</Profiles>
</ResUser2>
</ResUser>
</Infos>
</Info>
</OTA_Example>
</Body>
</Envelope>
GivenName is not an attribute, so you shouldn't use # for it.
It's unclear why you needed .nodes, it is only needed if there were multiple nodes that needed breaking out into separate rows
You can also select straight out of ExampleTable, you do not need to store it in a variable.
;WITH XMLNAMESPACES (
'http://www.w3.org/2003/05/soap-envelope' AS soap,
DEFAULT 'http://www.opentravel.org/OTA/2003/05')
select FirstName = [XML].value('(soap:Envelope/soap:Body/OTA_Example/Info/Infos/ResUser/ResUser2/Profiles/ProfileInfo/Profile/Customer/PersonName/GivenName/text())[1]', 'nvarchar(255)')
FROM ExampleTable
db<>fiddle

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

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

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.

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!