How to parse xml array in Oracle - sql
I have a xml with accounts array, if the array has 1 account this code works fine, but if the array has more than one account this code doesn't work. Please help.
select x.acc_num --into res
from xmltable (
xmlnamespaces (
default 'http://www.eubank.kz/Bis.Info.ExternalServices.Bank',
'http://schemas.xmlsoap.org/soap/envelope/' AS "s",
'http://www.w3.org/2001/XMLSchema-instance' as "i",
'http://schemas.microsoft.com/2003/10/Serialization/Arrays' as "a"
),
's:Envelope/s:Body/TryGetCardAccountsResponse/TryGetCardAccountsResult/IbanList'
passing xmltype(
'<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<TryGetCardAccountsResponse
xmlns="http://www.eubank.kz/Bis.Info.ExternalServices.Bank">
<TryGetCardAccountsResult
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<IbanList
xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:string>KZ199480018A00166666</a:string>
<a:string>KZ519480061A02366666</a:string>
</IbanList>
<Status>Ok</Status>
</TryGetCardAccountsResult>
</TryGetCardAccountsResponse>
</s:Body>
</s:Envelope>'
)
columns
acc_num varchar2(255) path 'a:string'
) x;
Try:
select x.acc_num --into res
from xmltable (
xmlnamespaces (
default 'http://www.eubank.kz/Bis.Info.ExternalServices.Bank',
'http://schemas.xmlsoap.org/soap/envelope/' AS "s",
'http://www.w3.org/2001/XMLSchema-instance' as "i",
'http://schemas.microsoft.com/2003/10/Serialization/Arrays' as "a"
),
's:Envelope/s:Body/TryGetCardAccountsResponse/TryGetCardAccountsResult/IbanList/a:string'
passing xmltype(
'<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<TryGetCardAccountsResponse
xmlns="http://www.eubank.kz/Bis.Info.ExternalServices.Bank">
<TryGetCardAccountsResult
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<IbanList
xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:string>KZ199480018A00166666</a:string>
<a:string>KZ519480061A02366666</a:string>
</IbanList>
<Status>Ok</Status>
</TryGetCardAccountsResult>
</TryGetCardAccountsResponse>
</s:Body>
</s:Envelope>'
)
columns
acc_num varchar2(255) path '.'
) x;
Related
How to get XML subnodes as strings along with parent attributes?
I need to parse xml which consist of nodes having attributes and subnodes. The result should be attribute of parent with xml of child node declare #xml xml set #xml = '<root> <group Description="firstgroup"> <nodeA age="10" birthplace="Anchorage"/> <nodeB mode="A" ability="read"/> </group> <group Description="nextgroup"> <nodeA age="10" birthplace="London"/> <nodeB count="2" birthplace="Paris"/> </group> </root>' select c.value('#Description', 'varchar(max)') as 'Description' from #xml.nodes('/root/*') as T(c) The output is Description =========== firstgroup nextgroup But I need Description nodeBXML =========== ======== firstgroup <nodeB mode="A" ability="read"/> nextgroup <nodeB count="2" birthplace="Paris"/>
select c.value('#Description', 'varchar(max)') as 'Description' , c.query('./nodeB') as Content from #xml.nodes('/root/*') as T(c) -- Results to: Description Content firstgroup <nodeB mode="A" ability="read" /> nextgroup <nodeB count="2" birthplace="Paris" />
Perhaps something like this: Example Select c.value('#Description', 'varchar(max)') as 'Description' ,AsString = convert(varchar(max),c.query('./*[2]') ) ,AsXML = c.query('./*[2]') From #xml.nodes('/root/*') as T(c) Returns
Returning XML structures with SQL
Using the next SQL code, running with Oracle 10: SELECT xmlserialize ( document xmlelement ( "Response", xmlforest ( '00' AS "ReturnCode" ), xmlagg ( xmlelement ( "Students", xmlelement ( "Student", xmlforest ( 'Some 1' AS "Name", '1' AS "Id" ) ), xmlelement ( "Student", xmlforest ( 'Some 2' AS "Name", '2' AS "Id" ) ) ) ) ) AS CLOB INDENT ) FROM dual ... I get this XML structure: <Response> <ReturnCode>00</ReturnCode> <Students> <Student> <Name>Some 1</Name> <Id>1</Id> </Student> <Student> <Name>Some 2</Name> <Id>2</Id> </Student> </Students> </Response> ... but, I want to get this one (removing the 'root' element): <ReturnCode>00</ReturnCode> <Students> <Student> <Name>Some 1</Name> <Id>1</Id> </Student> <Student> <Name>Some 2</Name> <Id>2</Id> </Student> </Students> Several attemps like this didnt work. Is mandatory to have a root element?: SELECT xmlserialize ( document xmlforest ( '00' AS "ReturnCode" ), xmlagg ( xmlelement ( "Students", xmlelement ( "Student", xmlforest ( 'Some 1' AS "Name", '1' AS "Id" ) ), xmlelement ( "Student", xmlforest ( 'Some 2' AS "Name", '2' AS "Id" ) ) ) ) AS CLOB INDENT ) FROM dual Any help will be appreciated. (This is just a simplification of something more complex I need to do in some project).
The question is why you need this? XML should be "Well Formed" This means: - XML documents must have a root element - XML elements must have a closing tag - XML tags are case sensitive - XML elements must be properly nested - XML attribute values must be quoted Add extract('/*/*') and change document -> content SELECT xmlserialize ( content xmlelement ( "Response", xmlforest ( '00' AS "ReturnCode" ), xmlagg ( xmlelement ( "Students", xmlelement ( "Student", xmlforest ( 'Some 1' AS "Name", '1' AS "Id" ) ), xmlelement ( "Student", xmlforest ( 'Some 2' AS "Name", '2' AS "Id" ) ) ) ) ).extract('/*/*') AS CLOB INDENT ) FROM dual
The easiest working way i could think is to use replace. See below: Select replace(Replace(col,'< >',''),'</ >','') from ( SELECT xmlserialize ( document xmlelement ( " ", xmlforest --Putting a wide space to differentiate from other tags ( '00' AS "ReturnCode" ), xmlagg ( xmlelement ( "Students", xmlelement ( "Student", xmlforest ( 'Some 1' AS "Name", '1' AS "Id" ) ), xmlelement ( "Student", xmlforest ( 'Some 2' AS "Name", '2' AS "Id" ) ) ) ) ) ) AS COL FROM dual ) Output: <ReturnCode>00</ReturnCode> <Students> <Student> <Name>Some 1</Name> <Id>1</Id> </Student> <Student> <Name>Some 2</Name> <Id>2</Id> </Student> </Students> DEMO
Removing the root element means you will no longer have a valid XML structure, but rather a sequence of XML structures. You could construct this by using xmlserialize(content ...) instead of xmlserialize(document ....). SELECT xmlserialize(content xmlforest( '00' as "ReturnCode", xmlforest( xmlforest('Some 1' AS "Name", '1' AS "Id" ) AS "Student", xmlforest('Some 2' AS "Name", '2' AS "Id" ) AS "Student" ) AS "Students" ) AS CLOB INDENT) FROM DUAL; You could also use xmlconcat and xmlelement instead of xmlforest, if you prefer: SELECT xmlserialize(content xmlconcat( xmlelement("ReturnCode", '00'), xmlelement("Students", xmlelement("Student", xmlelement("Name", 'Some 1'), xmlelement("Id", '1') ), xmlelement("Student", xmlelement("Name", 'Some 2'), xmlelement("Id", '2') ) ) ) AS CLOB INDENT) FROM DUAL;
How to convert a string in format "property:value,property2:value" to xml in SQL Server 2008
I need to convert the following text to XML {"name":"daniel & sophia","age":20,"year":2009,"weight":15.1,"points":3,"alias":"dani,da"}{"name":"charls & lina","age":22,"year":2007,"weight":19.0"points":3,"alias":"carlos,lini"} to <participants> <participant> <name>daniel & sophia</name> <age>20</age> <year>2009</year> <weight>15.1</weight> <points>3</points> <alias>dani,da</alias> </participant> <participant> <name>charls & lina</name> <age>22</age> <year>2007</year> <weight>19.0</weight> <points>3</points> <alias>carlos,lini</alias> </participant> <participants> I tried to insert the data to a temporary table and then replace "{}" characteres. Then I tried to convert with XML function but I really don't know how to replicate the name of each item. IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp CREATE TABLE #tmp ( Id INT IDENTITY, Campo VARCHAR(MAX) ) INSERT INTO #tmp ( Campo ) VALUES ( '{"name":"daniel & sophia","age":20,"year":2009,"weight":15.1,"points":3,"alias":"dani,da"}{"name":"charls & lina","age":22,"year":2007,"weight":19.0"points":3,"alias":"carlos,lini"}' ) SELECT CONVERT ( XML, '<participants>' + REPLACE ( REPLACE ( REPLACE ( REPLACE(REPLACE((SELECT Campo AS [*] FOR XML PATH('')), '{', '<participant>'),'}','</participant>') + '</participants>' ,'<participant>"' ,'<participant><dato>' ) , '","' , '</dato><dato>' ) , '</participant>' , '</dato></participant>' ) ) AS xmlname FROM #tmp And this is what I get, but It is wrong: <participants> <participant> <dato>name":"daniel & sophia</dato> <dato>age":20,"year":2009,"weigth":15.1,"points":3,"alias":"dani,da"</dato> </participant> <participant> <dato>name":"charls & lina</dato> <dato>age":22,"year":2007,"weigth":19.0,"points":3,"alias":"carlos,lini"</dato> </participant> </participants> NOTE: The amount of The number of nodes within the Participant node is unknown, it can be more than 100 and I would really like it to be a dynamic query. (Without using EXEC "sql code")
John Cappelletti's answer is great, as long, as you know the column names in advance. The following approach will help you in cases, where you have to deal with such structures dynamically. It is ugly, to create XML on string level (as I do it in the final SELECT like SELECT '<' + innerNvp.Name + '>' +, but it is a working possibility to deal with column names dynamically. Otherwise you'd either have to know all columns in advance, or you'd need to go the path of dynamic SQL with EXEC. There's one thing to keep in mind: The names in your structure (like "name" must be valid XML-tag-names. one general hint: All approaches here try to cut your parts on string level. This might break, if there is a } or a ," or a : in an unexpected place... DECLARE #str NVARCHAR(MAX)='{"name":"daniel & sophia","age":20,"year":2009,"weigth":15.1,"points":3,"alias":"dani,da"}{"name":"charls & lina","age":22,"year":2009,"weigth":15.1,"points":3,"alias":"carlos,lini"}'; WITH SplittedAtClosingCurly AS ( SELECT CAST('<x>' + REPLACE((SELECT #str AS [*] FOR XML PATH('')),'}','</x><x>') + '</x>' AS XML) AS TheRows ) ,SplittedAtCommaQuote AS ( SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNr ,CAST('<x>' + REPLACE((SELECT Rw.value(N'text()[1]','nvarchar(max)') AS [*] FOR XML PATH('')),',"','</x><x>') + '</x>' AS XML) AS TheRow FROM SplittedAtClosingCurly CROSS APPLY TheRows.nodes(N'/x[text()]') AS A(Rw) ) ,SplittedAtDoubleDot AS ( SELECT RowNr ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS TplNr ,CAST('<x>' + REPLACE((SELECT Tpl.value(N'text()[1]','nvarchar(max)') AS [*] FOR XML PATH('')),':','</x><x>') + '</x>' AS XML) AS TheTupel FROM SplittedAtCommaQuote CROSS APPLY TheRow.nodes(N'/x[text()]') AS A(Tpl) ) ,DerivedTable_NameValuePairs AS ( SELECT RowNr ,TplNr ,REPLACE(REPLACE(TheTupel.value(N'/x[1]/text()[1]','nvarchar(max)'),'{',''),'"','') AS Name ,REPLACE(REPLACE(TheTupel.value(N'/x[2]/text()[1]','nvarchar(max)'),'{',''),'"','') AS Value FROM SplittedAtDoubleDot ) SELECT CAST( ( SELECT '<' + innerNvp.Name + '>' + (SELECT innerNvp.Value AS [*] FOR XML PATH('')) + '</' + innerNvp.Name + '>' FROM DerivedTable_NameValuePairs AS innerNvp WHERE innerNvp.RowNr=nvp.RowNr ORDER BY TplNr FOR XML PATH(''),TYPE ).value(N'text()[1]','nvarchar(max)') AS XML) FROM DerivedTable_NameValuePairs AS nvp GROUP BY RowNr FOR XML PATH('participant'),ROOT('participants')
This query returns an equivalent attribute-type xml like this IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp CREATE TABLE #tmp ( Id INT IDENTITY, Campo VARCHAR(MAX) ) INSERT INTO #tmp ( Campo ) VALUES ( '{"name":"daniel & sophia","age":20,"year":2009,"weigth":15.1,"points":3,"alias":"dani,da"}{"name":"charls & lina","age":22,"year":2009,"weigth":15.1,"points":3,"alias":"carlos,lini"}' ) SELECT (select (CAST(replace(replace(replace(replace(replace(replace( replace(replace(Replace(t.Campo, '{"', '<participant '), '"}','" />'), '":"', '":'),'","',',"') , '":', '":"'),',"','","'), '":"', '="'), '","', '" '), '&',',') AS XML) ) FOR XML PATH (''), ROOT ('participants')) as xml FROM #tmp t & is illegal in xml, then i replaced it with ,. Result: <participants> <participant name="daniel , sophia" age="20" year="2009" weigth="15.1" points="3" alias="dani,da"/> <participant name="charls , lina" age="22" year="2009" weigth="15.1" points="3" alias="carlos,lini"/> </participants>
** -- Updated for Updated Question --** With the help of a Parse/Split UDF. Just about any Parse/Split UDF would do the trick. I did however supply mine. This approach can be applied to any portion of your core data. Example Declare #YourTable table (ID int,Campo varchar(max)) Insert Into #YourTable values (1,'{"name":"daniel & sophia","age":20,"year":2009,"weight":15.1,"points":3,"alias":"dani,da"}{"name":"charls & lina","age":22,"year":2007,"weight":19.0"points":3,"alias":"carlos,lini"}') Select [name] = max(case when Item='name' then Value end) ,[age] = max(case when Item='age' then Value end) ,[year] = max(case when Item='year' then Value end) ,[weight] = max(case when Item='weight' then Value end) ,[points] = max(case when Item='points' then Value end) ,[alias] = max(case when Item='alias' then Value end) From ( Select A.ID ,RowNr = B.RetSeq ,Item = replace(replace(left(C.RetVal,charindex(':',C.RetVal)-1),'"',''),'{','') ,Value = replace(replace(right(C.RetVal,len(C.RetVal)-charindex(':',C.RetVal)),'"',''),'}','') From #YourTable A Cross Apply [dbo].[udf-Str-Parse](A.Campo,'}{') B -- NOTE: Should really be },{ Cross Apply [dbo].[udf-Str-Parse](B.RetVal,',"') C -- YOUR WHERE STATEMENT HERE ) A Group By ID,RowNr Order By ID,RowNr For XML Path('participant'),Root('participants'),Type Returns <participants> <participant> <name>daniel & sophia</name> <age>20</age> <year>2009</year> <weight>15.1</weight> <points>3</points> <alias>dani,da</alias> </participant> <participant> <name>charls & lina</name> <age>22</age> <year>2007</year> <weight>19.0points:3</weight> <alias>carlos,lini</alias> </participant> </participants> The UDF if Interested CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#Delimiter varchar(10)) Returns Table As Return ( Select RetSeq = Row_Number() over (Order By (Select null)) ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) From (Select x = Cast('<x>' + replace((Select replace(#String,#Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A Cross Apply x.nodes('x') AS B(i) ); --Thanks Shnugo for making this XML safe --Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',') --Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ') --Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',') One final note: If you can't use or want an UDF, this can easily be converted to in-line. EDIT - In-line Approach Select [name] = max(case when Item='name' then Value end) ,[age] = max(case when Item='age' then Value end) ,[year] = max(case when Item='year' then Value end) ,[weight] = max(case when Item='weight' then Value end) ,[points] = max(case when Item='points' then Value end) ,[alias] = max(case when Item='alias' then Value end) From ( Select A.ID ,RowNr = B.RetSeq ,Item = replace(replace(left(C.RetVal,charindex(':',C.RetVal)-1),'"',''),'{','') ,Value = replace(replace(right(C.RetVal,len(C.RetVal)-charindex(':',C.RetVal)),'"',''),'}','') From YourTable A Cross Apply ( Select RetSeq = Row_Number() over (Order By (Select null)) ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) From (Select x = Cast('<x>' + replace((Select replace(A.Campo,'}{','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A Cross Apply x.nodes('x') AS B(i) ) B Cross Apply ( Select RetSeq = Row_Number() over (Order By (Select null)) ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) From (Select x = Cast('<x>' + replace((Select replace(B.RetVal,',"','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A Cross Apply x.nodes('x') AS B(i) ) C -- Your WHERE STATEMENT here -- ) A Group By ID,RowNr Order By ID,RowNr For XML Path('participant'),Root('participants'),Type
I add this as a new answer, it is an addition to TriV's answer actually: The transformation to attribute centered XML is a good idea. You might go one step further with a FLWOR XQuery approach: DECLARE #xml XML= N'<participants> <participant name="daniel & sophia" age="20" year="2009" weigth="15.1" points="3" alias="dani,da"/> <participant name="charls & lina" age="22" year="2009" weigth="15.1" points="3" alias="carlos,lini"/> </participants>'; SELECT #xml.query (' <participants> { for $p in /participants/participant return <participant> { for $attr in $p/#* return <data name="{local-name($attr)}" value="{string($attr)}"/> } </participant> } </participants> '); The result <participants> <participant> <data name="name" value="daniel & sophia" /> <data name="age" value="20" /> <data name="year" value="2009" /> <data name="weigth" value="15.1" /> <data name="points" value="3" /> <data name="alias" value="dani,da" /> </participant> <participant> <data name="name" value="charls & lina" /> <data name="age" value="22" /> <data name="year" value="2009" /> <data name="weigth" value="15.1" /> <data name="points" value="3" /> <data name="alias" value="carlos,lini" /> </participant> </participants> Regrettfully this approach does not support dynamically created elements. UPDATE: Slightly different, even closer: The following query will place the values as element's text(), while the element's name is still an attribute... SELECT #xml.query (' <participants> { for $p in /participants/participant return <participant> { for $attr in $p/#* return <data name="{local-name($attr)}">{string($attr)}</data> } </participant> } </participants>'); The result <participants> <participant> <data name="name">daniel & sophia</data> <data name="age">20</data> <data name="year">2009</data> <data name="weigth">15.1</data> <data name="points">3</data> <data name="alias">dani,da</data> </participant> <participant> <data name="name">charls & lina</data> <data name="age">22</data> <data name="year">2009</data> <data name="weigth">15.1</data> <data name="points">3</data> <data name="alias">carlos,lini</data> </participant> </participants>
ORA-19228: XPST0008 - undeclared identifier in oracle sql
I have xml string which i have mentioned below and i want to extract code from xml string. I have written below select query to extract the value from <ax2140:code>0</ax2140:code> which is 0 but i am getting error as ORA-19228: XPST0008 - undeclared identifier: prefix 'ax2140' local-name 'ax2140:code' 19228. 00000 - "XPST0008 - undeclared identifier: prefix '%s' local-name '%s'" Here is my xml string- <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <ns:placeShopOrderResponse xmlns:ns="http://service.soap.CDRator.com"> <ns:return xmlns:ax2127="http://data.soap.CDRator.com/xsd" xmlns:ax2129="http://webshop.data.soap.CDRator.com/xsd" xmlns:ax2130="http://core.data.soap.CDRator.com/xsd" xmlns:ax2133="http://signup.data.soap.CDRator.com/xsd" xmlns:ax2134="http://core.signup.data.soap.CDRator.com/xsd" xmlns:ax2139="http://result.service.soap.CDRator.com/xsd" xmlns:ax2140="http://core.result.service.soap.CDRator.com/xsd" xmlns:ax2147="http://webshop.result.service.soap.CDRator.com/xsd" xmlns:ax2148="http://mandate.result.service.soap.CDRator.com/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax2147:PlaceShopOrderResultDTO"> <ax2130:id xsi:nil="true" /> <ax2140:code>0</ax2140:code> <ax2140:description>OK</ax2140:description> <ax2127:statusId>1</ax2127:statusId> <ax2127:subscriptionCondition xsi:type="ax2127:SubscriptionStatusDTO"> <ax2130:id xsi:nil="true" /> <ax2140:code>0</ax2140:code> <ax2140:description>OK</ax2140:description> <ax2130:imsi xsi:nil="true" /> <ax2130:phoneNumber>NO_NUMBER</ax2130:phoneNumber> <ax2127:imei xsi:nil="true" /> <ax2127:simCard xsi:nil="true" /> </ax2127:teleService> </ax2147:subscriptions> </ns:return> </ns:placeShopOrderResponse> </soapenv:Body> </soapenv:Envelope> Here is my select query: SELECT ID,xt_code.CODE FROM TEMP_SOAP_MONITORING_MSP sm CROSS JOIN XMLTable(XMLNAMESPACES ( 'http://core.result.service.soap.CDRator.com/xsd' as "ax2140_code" ), 'for $i in //ax2140:code return $i' passing XMLType(sm.RESPONSE_XML) columns "CODE" VARCHAR2(50) path '/') xt_code;
Use "ax2140" instead of "ax2140_code" in the query.
how to get xsd element format result from sql script
I need to create xml files to migrate a huge amount of data from one database to another database. How to get result xsd format as below from ms sql script query? Please share if you have any idea. The xml file format is below: <Batch> <retail:customer xmlns:core="http://www.bactor.com/core" xmlns:retail=""http://www.bactor.com/retail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <retail:addresses> <retail:address> <retail:country>GB</retail:country> <retail:countryCodeId></retail:countryCodeId> <retail:isPreferred>true</retail:isPreferred> <retail:isActive>true</retail:isActive> <retail:typeId>PERSONAL_ADDRESS</retail:typeId> <retail:postCode>2344</retail:postCode> <retail:street1>1234214</retail:street1> <retail:isTemplate>false</retail:isTemplate> <retail:referenceId></retail:referenceId> <retail:addressReferenceId>0727-:83f5bd9f331:e8e438a1:fa34668911272008</retail:addressReferenceId> </retail:address> </retail:addresses> <retail:contactMethod></retail:contactMethod> <retail:contactable>false</retail:contactable> <retail:maritalStatus></retail:maritalStatus> <retail:nationality></retail:nationality> <retail:noChildren>0</retail:noChildren> <retail:customerNumber>1</retail:customerNumber> <retail:emailAddresses> <retail:emailAddress>alice#wonderland.hearts</retail:emailAddress> <retail:preferred>true</retail:preferred> <retail:restrictedReason></retail:restrictedReason> <retail:status></retail:status> <retail:typeId>PERSONAL_EMAIL</retail:typeId> <retail:referenceId></retail:referenceId> <retail:active>false</retail:active> </retail:emailAddresses> <retail:phoneNumbers> <retail:countryCode></retail:countryCode> <retail:number>11222445566</retail:number> <retail:preferred>true</retail:preferred> <retail:restrictedReason></retail:restrictedReason> <retail:status></retail:status> <retail:typeId>LANDLINE</retail:typeId> <retail:referenceId></retail:referenceId> <retail:active>true</retail:active> <retail:phoneNumberReferenceId>e437-:83f5bd9f331:e8e438a1:fa34668911272008</retail:phoneNumberReferenceId> </retail:phoneNumbers> <retail:customerName> <retail:surname>AppleGate</retail:surname> <retail:forename>Alice</retail:forename> <retail:title>Mrs</retail:title> <retail:sex>FEMALE</retail:sex> <retail:dateOfBirth>2012-09-12T00:00:00+01:00</retail:dateOfBirth> </retail:customerName> <retail:businessContactMethod></retail:businessContactMethod> <retail:preferredContactTime></retail:preferredContactTime> <retail:allowInternalMarketing>true</retail:allowInternalMarketing> <retail:allowExternalMarketing>true</retail:allowExternalMarketing> <retail:employeeKey></retail:employeeKey> <retail:customerType>RETAIL</retail:customerType> <retail:organisation></retail:organisation> <retail:taxIdentification></retail:taxIdentification> <retail:companyNumber></retail:companyNumber> <retail:createdBy></retail:createdBy> <retail:createdAt></retail:createdAt> <retail:status>New</retail:status> <retail:source></retail:source> </retail:customer> <retail:customer xmlns:core="http://www.enactor.com/core" xmlns:retail="http://www.enactor.com/retail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <retail:addresses> <retail:address> <retail:country>GB</retail:country> <retail:countryCodeId></retail:countryCodeId> <retail:isPreferred>true</retail:isPreferred> <retail:isActive>true</retail:isActive> <retail:typeId>PERSONAL_ADDRESS</retail:typeId> <retail:postCode>2344</retail:postCode> <retail:street1>1234214</retail:street1> <retail:isTemplate>false</retail:isTemplate> <retail:referenceId></retail:referenceId> <retail:addressReferenceId>0727-:83f5bd9f331:e8e438a1:fa34668911272008</retail:addressReferenceId> </retail:address> </retail:addresses> <retail:contactMethod></retail:contactMethod> <retail:contactable>false</retail:contactable> <retail:maritalStatus></retail:maritalStatus> <retail:nationality></retail:nationality> <retail:noChildren>0</retail:noChildren> <retail:customerNumber>1</retail:customerNumber> <retail:emailAddresses> <retail:emailAddress>alice#wonderland.hearts</retail:emailAddress> <retail:preferred>true</retail:preferred> <retail:restrictedReason></retail:restrictedReason> <retail:status></retail:status> <retail:typeId>PERSONAL_EMAIL</retail:typeId> <retail:referenceId></retail:referenceId> <retail:active>false</retail:active> </retail:emailAddresses> <retail:phoneNumbers> <retail:countryCode></retail:countryCode> <retail:number>11222445566</retail:number> <retail:preferred>true</retail:preferred> <retail:restrictedReason></retail:restrictedReason> <retail:status></retail:status> <retail:typeId>LANDLINE</retail:typeId> <retail:referenceId></retail:referenceId> <retail:active>true</retail:active> <retail:phoneNumberReferenceId>e437-:83f5bd9f331:e8e438a1:fa34668911272008</retail:phoneNumberReferenceId> </retail:phoneNumbers> <retail:customerName> <retail:surname>AppleGate</retail:surname> <retail:forename>Alice</retail:forename> <retail:title>Mrs</retail:title> <retail:sex>FEMALE</retail:sex> <retail:dateOfBirth>2012-09-12T00:00:00+01:00</retail:dateOfBirth> </retail:customerName> <retail:businessContactMethod></retail:businessContactMethod> <retail:preferredContactTime></retail:preferredContactTime> <retail:allowInternalMarketing>true</retail:allowInternalMarketing> <retail:allowExternalMarketing>true</retail:allowExternalMarketing> <retail:employeeKey></retail:employeeKey> <retail:customerType>RETAIL</retail:customerType> <retail:organisation></retail:organisation> <retail:taxIdentification></retail:taxIdentification> <retail:companyNumber></retail:companyNumber> <retail:createdBy></retail:createdBy> <retail:createdAt></retail:createdAt> <retail:status>New</retail:status> <retail:source></retail:source> </retail:customer> </Batch> I am also trying with the below a pieces of sql script. but it is not working. WITH XMLNAMESPACES ('http://www.enactor.com/retail' as ns1) SELECT top 100 [id] ,[Title] ,[First_Name] , RowNum = Row_NUMBER() OVER (Order by id) FROM [Firinne].[dbo].[Contact] as Customer For XML PATH('retail:Customer')
Try this: DECLARE #xml XML ;WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema-instance' AS xsi, 'http://www.bactor.com/retail' AS retail, 'http://www.bactor.com/core' AS core) SELECT #xml = (SELECT [retail:Customer].id AS [retail:id], [retail:Customer].contactMethod AS [retail:contactMethod], [retail:Customer].contactable AS [retail:contactable], [retail:address].emailAddress AS [retail:emailAddress], [retail:address].typeId AS [retail:typeId] FROM dbo.Customers AS [retail:Customer] JOIN dbo.emailAddresses AS [retail:address] ON [retail:Customer].id = [retail:address].customerID FOR XML AUTO, ELEMENTS) SET #xml = '<Batch>' + CAST(#xml AS NVARCHAR(max)) + '</Batch>' SELECT #xml Output: <Batch> <retail:Customer xmlns:core="http://www.bactor.com/core" xmlns:retail="http://www.bactor.com/retail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <retail:id>1</retail:id> <retail:contactMethod>1</retail:contactMethod> <retail:contactable>1</retail:contactable> <retail:address> <retail:emailAddress>some#some.some</retail:emailAddress> <retail:typeId>1</retail:typeId> </retail:address> <retail:address> <retail:emailAddress>some#some.some</retail:emailAddress> <retail:typeId>2</retail:typeId> </retail:address> </retail:Customer> <retail:Customer xmlns:core="http://www.bactor.com/core" xmlns:retail="http://www.bactor.com/retail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <retail:id>2</retail:id> <retail:contactMethod>1</retail:contactMethod> <retail:contactable>0</retail:contactable> <retail:address> <retail:emailAddress>some#some.some</retail:emailAddress> <retail:typeId>3</retail:typeId> </retail:address> </retail:Customer> </Batch> EDIT: You can do it like: DECLARE #xml XML ;WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema-instance' AS xsi, 'http://www.bactor.com/retail' AS retail, 'http://www.bactor.com/core' AS core) SELECT #xml = (SELECT [retail:Customer].id AS [retail:id], [retail:Customer].contactMethod AS [retail:contactMethod], [retail:Customer].contactable AS [retail:contactable], (SELECT [retail:address].emailAddress , [retail:address].typeId FROM dbo.emailAddresses AS [retail:address] WHERE [retail:Customer].id = [retail:address].customerID FOR XML AUTO, TYPE, ELEMENTS, ROOT('retail:Addresses') ) FROM dbo.Customers AS [retail:Customer] FOR XML AUTO, ELEMENTS) SET #xml = '<Batch>' + CAST(#xml AS NVARCHAR(max)) + '</Batch>' SELECT #xml But namespaces are added to all child: <Batch> <retail:Customer xmlns:core="http://www.bactor.com/core" xmlns:retail="http://www.bactor.com/retail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <retail:id>1</retail:id> <retail:contactMethod>1</retail:contactMethod> <retail:contactable>1</retail:contactable> <retail:Addresses xmlns:core="http://www.bactor.com/core" xmlns:retail="http://www.bactor.com/retail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <retail:address> <emailAddress>some#some.some</emailAddress> <typeId>1</typeId> </retail:address> <retail:address> <emailAddress>some#some.some</emailAddress> <typeId>2</typeId> </retail:address> </retail:Addresses> </retail:Customer> <retail:Customer xmlns:core="http://www.bactor.com/core" xmlns:retail="http://www.bactor.com/retail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <retail:id>2</retail:id> <retail:contactMethod>1</retail:contactMethod> <retail:contactable>0</retail:contactable> <retail:Addresses xmlns:core="http://www.bactor.com/core" xmlns:retail="http://www.bactor.com/retail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <retail:address> <emailAddress>some#some.some</emailAddress> <typeId>3</typeId> </retail:address> </retail:Addresses> </retail:Customer> </Batch> It is a known issue, and you can see details here: https://connect.microsoft.com/SQLServer/feedback/details/265956/suppress-namespace-attributes-in-nested-select-for-xml-statements Additional namespaces doesn't do any harm but increasing size of generated xml document.