Parse simple XML in SQL Server - sql-server

How to parse the following xml as recordset?
<root>
<240>0</240>
<241>1</241>
<242>2</242>
<243>3</243>
<249>4</249>
</root>
<root 240="0" 241="1" 242="2" 243="3" 249="4"/>
When I try
declare #ids xml = N'<root><240>0</240><241>1</241></root>'
SELECT T.Item.value('240[1]', 'int')
from #ids.nodes('/root') AS T(Item)
I get an error
ML parsing: line 1, character 8, illegal qualified name character: declare #ids xml = N'<240>0' SELECT T.Item.value('a[1]', 'int') from #ids.nodes('/root') AS T(Item)
But generally I need the following output:
|240|0|
|241|1|
...
When xml elements are named as usual everything is Ok (<row key=240 value="0"/>).

XML disallows to use numbers as first character of an element name. Use format from your example:
<row key=240 value="0"/>

Related

How to add additional attributes and XML namespaces value inside same root in SQL Server

I am trying to add attributes and xmlns using WITH XMLNAMESPACES under same root, but could not make it work. Please help.
The following SQL query throws an error
Msg 6852, Level 16, State 1, Line 17
Attribute-centric column '#encounter_number' must not come after a non-attribute-centric sibling in XML hierarchy in FOR XML PATH.
for this line
'HMSXML' AS "pbrc/#source" , URNumber AS "pbrc/#messageHash", 'xmlResult01' AS "pbrc/#integration_info"
Full code:
DECLARE #xml XML;
WITH XMLNAMESPACES (
'http://www.w3.org/2001/XMLSchema-instance' as xsi
,'http://java.sun.com/xml/ns/jaxb/xjc' as xjc
,'http://www.powerhealthsolutions.com/pbrc/jaxb/ext' as [pbrc-jaxb]
,'http://java.sun.com/xml/ns/jaxb' AS jaxb
,DEFAULT 'http://www.powerhealthsolutions.com/pbrc')
SELECT
#xml = (SELECT
'HMSXML' AS "pbrc/#source",
URNumber AS "pbrc/#messageHash",
'xmlResult01' AS "pbrc/#integration_info",
AdmissionID AS "#encounter_number",
'NDIS' AS organisation_code,
'NDIS' AS encounter_type,
(SELECT
'true' AS "#delete",
(SELECT 'NDIS' AS class_type, AdmissionDate AS start_date_time
FOR XML PATH ('financial_class'), TYPE)
FOR XML PATH('financial_classes'), TYPE),
(SELECT
URNumber AS "#entity_number",
(SELECT 'NDIS ID' AS name, NDISNumber AS value
FOR XML PATH ('extra'), ROOT('extras'), TYPE)
FOR XML PATH ('recipient'), TYPE),
'H' AS referral_source,
'H' AS separation_status,
AdmissionDate AS start_date_time
FROM
Episode
FOR XML PATH('encounter'), ROOT('pbrc'), TYPE)
select #xml
I want to get output as shown here, but I'm failing to achieve those last 3 attributes integration_info="xmlResult03", messageHash="4208151" and source="HMSXML". These will come from SQL select query.
<?xml version="1.0"?>
-<pbrc xmlns="http://www.powerhealthsolutions.com/pbrc" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:pbrc-jaxb="http://www.powerhealthsolutions.com/pbrc/jaxb/ext" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" integration_info="xmlResult03" messageHash="4208151" source="HMSXML">
-<encounter encounter_number="525241">
<organisation_code>NDIS</organisation_code>
<encounter_type>NDIS</encounter_type>
-<financial_classes delete="true">
-<financial_class>
<class_type>NDIS</class_type>
<start_date_time>2018-06-26T00:00:00</start_date_time>
</financial_class>
</financial_classes>
-<payors>
-<payor>
<payor entity_number="4208151"> </payor>
<slot>Patient</slot>
<start_date>2018-06-26</start_date>
</payor>
</payors>
-<recipient entity_number="4208151">
-<extras>
-<extra>
<name>NDIS ID</name>
<value>430392519</value>
</extra>
</extras>
</recipient>
<referral_source>H</referral_source>
<separation_status>H</separation_status>
-<services>
-<service>
<source_system_code>HMSXML</source_system_code>
<organisation_code>NDIS</organisation_code>
<actual_charge>179.26</actual_charge>
<description1>Arnold Sch - Occupational Therapist</description1>
<quantity>1</quantity>
<service_code>15_048_0128_1_3</service_code>
<start_time>2019-03-27T15:00:00</start_time>
</service>
-<service>
<source_system_code>HMSXML</source_system_code>
<organisation_code>NDIS</organisation_code>
<actual_charge>193.99</actual_charge>
<description1>Arnold Sch - Occupational Therapist</description1>
<quantity>1</quantity>
<service_code>15_056_0128_1_3</service_code>
<start_time>2019-07-30T15:00:00</start_time>
</service>
</services>
<start_date_time>2018-06-26T00:00:00</start_date_time>
</encounter>
</pbrc>

SQL replace value of with always random xml code

I have the following SQL XML in several rows of a table (table is tbldatafeed column in configuration_xml). All of the UserName="" and Password="" is different each time for each row and does not repeat so I can not find/replace off of that. I am trying to write a query that finds all of those and replaces them with Username/Passwords I choose.
<DataFeed xmlns="http://www.tech.com/datafeed/dfx/2010/04" xmlns:plugin="pluginExtensions" Type="TODO" Guid="TODO" UserAccount="DF_LEAN_PopulateCommentsSubForm" Locale="en-US" DateFormat="" ThousandSeparator="" NegativeSymbol="" DecimalSymbol="" SendingNotifications="false" SendJobStatusNotifications="false" RecipientUserIds="" RecipientGroupIds="" RecipientEmailAddresses="" Name="CI_C11.01_Lean-Lean_Reject Comments_A2A" >
<Transporter>
<transporters:ArcherWebServiceTransportActivity xmlns:transporters="clr-namespace:ArcherTech.DataFeed.Activities.Transporters;assembly=ArcherTech.DataFeed" xmlns:out="clr-namespace:ArcherTech.DataFeed;assembly=ArcherTech.DataFeed" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:compModel="clr-namespace:ArcherTech.DataFeed.ComponentModel;assembly=ArcherTech.DataFeed" xmlns:channel="clr-namespace:ArcherTech.DataFeed.Engine.Channel;assembly=ArcherTech.DataFeed" xmlns:engine="clr-namespace:ArcherTech.DataFeed.Engine;assembly=ArcherTech.DataFeed" xmlns:kernel="clr-namespace:ArcherTech.Kernel.Channel;assembly=ArcherTech.Kernel" xmlns="clr-namespace:ArcherTech.DataFeed;assembly=ArcherTech.DataFeed" xmlns:schema="clr-namespace:System.Xml.Schema;assembly=System.Xml" xmlns:xmlLinq="clr-namespace:System.Xml.Linq;assembly=System.Xml" xmlns:domain="clr-namespace:ArcherTech.Common.Domain;assembly=ArcherTech.Common" xmlns:s="clr-namespace:System;assembly=mscorlib" x:Key="transportActivity" SearchType="ReportId" Uri="https://arcs-d" RecordsPerFile="100" ReportID="EC514865-88D5-49CE-A200-7769EC1C2A88" UseWindowsAuth="false" IsWindowsAuthSpecific="false" WindowsAuthUserName="i9XzCczAQ7J2rHwkg6wG9QF8+O9NCYJZP6y5Kzw4be0+cdvUaGu/9+rHuLstU736pnQrRcwmnSIhd6oPKIvnLA==" WindowsAuthPassword="+y0tCAKysxEMSGv1unpHxfg6WjH5XWylgP45P5MLRdQ6+zAdOLSVy7s3KJa3+9j2i83qn8I8K7+1+QBlCJT1E7sLQHWRFOCEdJgXaIr1gWfUEO+7kjuJnZcIEKZJa2wHyqc2Z08J2SKfdCLh7HoLtg==" WindowsAuthDomain="" ProxyName="" ProxyPort="8080" ProxyUsername="" ProxyPassword="" ProxyDomain="" IsProxyActive="False" ProxyOption="None" InstanceName="ARCS-D" TempFileOnSuccessAction="DoNothing" TempFileOnSuccessRenameString="" TempFileOnErrorAction="DoNothing" TempFileOnErrorRenameString="" Transform="{engine:DataFeedBinding Path=Transform}" SessionContext="{engine:DataFeedBinding Path=Session}">
<transporters:ArcherWebServiceTransportActivity.Credentials>
<NetworkCredentialWrapper UserName="TeSZmI1SqO0eJ0G2nDVU+glFg/9eZfeMppYQnPfbeg8=" Password="Slt4VHqjkYscWyCwZK40QJ7KOQroG9OTKr+RGt9bQjE=" />
</transporters:ArcherWebServiceTransportActivity.Credentials>
</transporters:ArcherWebServiceTransportActivity>
</Transporter>
</DataFeed>
I need to be able to set a value and replace it with a query
I have written the following
select #config_xml=configuration_xml from bldatafeed where datafeed_name = 'REMOVED'
update tbldatafeed set configuration_xml.modify(//*:NetworkCredentialWrapper/#UserName)[1] with "abc" ')
where datafeed_name = 'REMOVED'
This does the trick but it only works if I set the "abc" password each time in each area and in some cases I am running this against 50+ rows.
I also tried:
Declare #server nvarchar(max) = 'abc'
Declare #config_xml xml
select #config_xml=configuration_xml from bldatafeed where datafeed_name = 'REMOVED'
update tbldatafeed set configuration_xml.modify(//*:NetworkCredentialWrapper/#UserName)[1] with #server ')
where datafeed_name = 'REMOVED'
The error from this is that: XQuery [tbldatafeed.configuration_xml.modify()]: Top-level attribute nodes are not supported
What I would like to be able to do is set my variable and utilize that as I will be setting this up for multiple rows and unfortunately this error is making this a very difficult problem to solve.
Thanks for any help, this has kept me confused for a bit.
Use the function sql:variable() to use a variable in the XQuery expression.
declare #T table(X xml);
insert into #T values('<X UserName=""/>');
declare #UserName nvarchar(max) = 'abc'
update #T set
X.modify('replace value of (/X/#UserName)[1]
with sql:variable("#UserName")');

Parse an XML value with a colon in SQL Server

I need help to parse XML in SQL Server. I need to get "d1p1:Val2" value and concatenation of values for "d2p1:string".
<FirstData xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns:d1p1="http://XXXXXX" xmlns="http://YYYYYY" i:type="d1p1:StaticInfo">
<Timestamp>0</Timestamp>
<ActionResult i:nil="true" />
<d1p1:Val1 xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>1</d2p1:string>
<d2p1:string>2</d2p1:string>
<d2p1:string>3</d2p1:string>
<d2p1:string>4</d2p1:string>
</d1p1:Val1>
<d1p1:Val2>false</d1p1:Val2>
</FirstData>
Your question is not very clear, but this might help you:
DECLARE #xml XML=
N'<FirstData xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d1p1="http://XXXXXX" xmlns="http://YYYYYY" i:type="d1p1:StaticInfo">
<Timestamp>0</Timestamp>
<ActionResult i:nil="true" />
<d1p1:Val1 xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>1</d2p1:string>
<d2p1:string>2</d2p1:string>
<d2p1:string>3</d2p1:string>
<d2p1:string>4</d2p1:string>
</d1p1:Val1>
<d1p1:Val2>false</d1p1:Val2>
</FirstData>';
WITH XMLNAMESPACES(DEFAULT 'http://YYYYYY'
,'http://XXXXXX' AS d1p1
,'http://schemas.microsoft.com/2003/10/Serialization/Arrays' AS d2p1)
SELECT #xml.value(N'(/FirstData/d1p1:Val2/text())[1]','bit') AS D1P1_Val2
,#xml.query(N'data(/FirstData/d1p1:Val1/d2p1:string/text())').value(N'text()[1]',N'nvarchar(max)') AS AllStrings;
The result
D1P1_Val2 AllStrings
0 1 2 3 4
This is the - not recommended - minimal query:
SELECT #xml.value(N'(//*:Val2)[1]','bit') AS D1P1_Val2
,#xml.query(N'data(//*:string)').value(N'.',N'nvarchar(max)') AS AllStrings;
Try something like this (can't test it myself ) :
SELECT Instructions.query('
declare namespace d1p1="http://XXXXXX";
declare namespace d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays";
concat(//d1p1:Val2, " ", //d2p1:string[1]);
')
I think you just have to elaborate a bit on this

What is exactly XML Path?

Can someone please explain with more detail what is actually SELECT (STUFF SELECT...))FOR XML PATH(''), TYPE).value('.','NVARCHAR(max)')
From what I know:
XmlPath('')to concatenate column data into single row.
Stuff is used to remove the first ‘,’ after string concatenation.
So what about TYPE).value('.','NVARCHAR(max)') use for ?
So what about TYPE).value('.','NVARCHAR(max)') use for ?
The basics of FOR XML PATH you can find in a lot of questions/answers on SO (e.g. 1, or 2).
I'll focus on the TYPE directive. Consider the following T-SQL statement which concatenates the strings in the derived table dt:
SELECT
[text()]=dt.x+';'
FROM
(
VALUES('text > blabla'),
('text < blabla'),
('f&m')
) AS dt(x)
FOR XML
PATH('');
The result is:
text > blabla;text < blabla;f&m;
You'll see that the >, < and & are substituted by the >, < and &. The special characters (XML predefined entities) will be replaced.
You can disable this by specifying the TYPE directive, which exports this as XML rather than text, then getting the string value from the XML. Getting this string value from the resulting XML, can be done by using the value() method.
Using the TYPE directive in the above example:
SELECT
(
SELECT
[text()]=dt.x+';'
FROM
(
VALUES('text > blabla'),
('text < blabla'),
('f&m')
) AS dt(x)
FOR XML
PATH(''), TYPE
).value('.','NVARCHAR(MAX)');
You'd get:
text > blabla;text < blabla;f&m;
You can see that the XML special characters are not substituted.

Extract data from XML string in SQL using XQuery

I am trying to extract data from a XML string which is stored in my table in XMLString column as below..
VId Uid Name TWd XMLString
26 jti jbreti testell string in xml format
26 Man Lomond Mcan string in xml format
26 mw mlwTest tewWell string in xml format
26 tot teapot te2Well string in xml format
XML string having below format. Its having multi level nodes also..
<well uid="b4e952f9">
<name>Demo</name>
<field>Fi Tk</field>
<country>India</country>
<county>South India</county>
<region>SiD</region>
<block>09-365</block>
<timeZone>+09:00</timeZone>
<operator>AACE Oil CO</operator>
<operatorDiv>AAACE South Australia</operatorDiv>
<statusWell>unknown</statusWell>
<wellDatum defaultElevation="true" uid="SL">
<name>Mean Sea Level</name>
<code>SL</code>
</wellDatum>
<waterDepth uom="ft">269.0256</waterDepth>
<wellLocation uid="loc-1">
<latitude uom="dega">-28.601403</latitude>
<longitude uom="dega">137.444458</longitude>
</wellLocation>
<commonData>
<dTimCreation>2012-04-10T13:17:45.959Z</dTimCreation>
<dTimLastChange>2013-11-08T14:42:56.340Z</dTimLastChange>
</commonData>
</well>
I required few nodes from above XML & this few nodes details is also in XML string as below..
<well>
<name></name>
<country></country>
<block></block>
<timeZone></timeZone>
<wellDatum>
<name></name>
<code></code>
</wellDatum>
<waterDepth></waterDepth>
</well>
Now i need to extract nodes from 1st XML with node values string that are present in 2nd XML string.
And out put should be also a XML string.
Output string should be as below....
<well uid="b4e952f9">
<name>Demo</name>
<country>India</country>
<block>09-365</block>
<timeZone>+09:00</timeZone>
<wellDatum defaultElevation="true" uid="SL">
<name>Mean Sea Level</name>
<code>SL</code>
</wellDatum>
<waterDepth uom="ft">269.0256</waterDepth>
</well>
This all i want to be done in MSSQL only.
Can anyone help me..
SELECT XMLString.query(
'<well>
<name>{/well/name/node()}</name>
<country>{/well/country/node()}</country>
<block>{/well/block/node()}</block>
<timeZone>{/well/timeZone/node()}</timeZone>
<wellDatum>
<name>{/well/wellDatum/name/node()}</name>
<code>{/well/wellDatum/code/node()}</code>
</wellDatum>
<waterDepth>{/well/waterDepth/node()}</waterDepth>
</well>'
),
XMLString FROM Well

Resources