I am trying to store an XML file (Code below) but the the dc:creator is causing an error. I have found from other related questions on here stating that I should use ;WITH XMLNAMESPACES(''http://purl.org/dc/elements/1.1/'' AS dc) but this has not worked either any ideas on what might be the problem/solution ? .
XML file:
<?xml version="1.0" encoding="UTF-8"?>
-<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="http://talksport.com/rss/sports-news/football/feed" version="2.0">
-<channel>
<title>Football</title>
<link>http://talksport.com/rss/sports-news/football/feed</link>
<description/>
<language>en</language>
<atom:link type="application/rss+xml" rel="self" href="http://talksport.com/rss/sports-news/football/feed"/>
-<item>
<title>Hillsborough families 'back introduction of rail seating' as bereaved family says 'standing did not kill our 96'</title>
<link>http://talksport.com/football/hillsborough-families-back-introduction-rail-seating-bereaved-family-says-standing-did-not</link>
<description/>
<pubDate>Wed, 19 Jul 2017 08:18:37 +0000</pubDate>
<dc:creator>talkSPORT</dc:creator>
<guid isPermaLink="false">247276 at http://talksport.com</guid>
</item>
</rss>
This is the stored procedure:
CREATE PROCEDURE feed.usp_importXML(#file VARCHAR(8000))
AS
BEGIN
DECLARE #Query VARCHAR(8000)
SET #Query ='
DECLARE #xmlFile as XML
SET #xmlFile = ( cast
SELECT CONVERT(XML,BulkColumn) as BulkColumn
FROM OPENROWSET (BULK '''+#file+''', SINGLE_BLOB) AS t)
INSERT INTO feed.tempXML (title,link,source)
SELECT
title = t.value (''title[1]'', ''NVARCHAR(300)''),
link = t.value (''link[1]'', ''NVARCHAR(300)''),
source = t.value(''(dc:creator)[1]'',''NVARCHAR(30)'')
FROM #xmlFile.nodes(''/rss/channel/item'') AS xTable(t);'
EXEC(#Query)
END
GO
In your case it might be enough to replace the dc: with a wildcard: *:. Assuming your XML is written into an XML file already, you might try as such:
DECLARE #xmlFile XML=
N'<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="http://talksport.com/rss/sports-news/football/feed" version="2.0">
<channel>
<title>Football</title>
<link>http://talksport.com/rss/sports-news/football/feed</link>
<description />
<language>en</language>
<atom:link type="application/rss+xml" rel="self" href="http://talksport.com/rss/sports-news/football/feed" />
<item>
<title>Hillsborough families ''back introduction of rail seating'' as bereaved family says ''standing did not kill our 96''</title>
<link>http://talksport.com/football/hillsborough-families-back-introduction-rail-seating-bereaved-family-says-standing-did-not</link>
<description />
<pubDate>Wed, 19 Jul 2017 08:18:37 +0000</pubDate>
<dc:creator>talkSPORT</dc:creator>
<guid isPermaLink="false">247276 at http://talksport.com</guid>
</item>
</channel>
</rss>';
SELECT
title = t.value ('title[1]', 'NVARCHAR(300)'),
link = t.value ('link[1]', 'NVARCHAR(300)'),
source = t.value('(*:creator)[1]','NVARCHAR(30)')
FROM #XmlFile.nodes('/rss/channel/item') AS xTable(t);
This will work too:
WITH XMLNAMESPACES('http://purl.org/dc/elements/1.1/' AS dc)
SELECT
title = t.value ('title[1]', 'NVARCHAR(300)'),
link = t.value ('link[1]', 'NVARCHAR(300)'),
source = t.value('(dc:creator)[1]','NVARCHAR(30)')
FROM #XmlFile.nodes('/rss/channel/item') AS xTable(t);
And you can declare the namespace within .value too:
SELECT
title = t.value ('title[1]', 'NVARCHAR(300)'),
link = t.value ('link[1]', 'NVARCHAR(300)'),
source = t.value('declare namespace dc="http://purl.org/dc/elements/1.1/";(dc:creator)[1]','NVARCHAR(30)')
FROM #XmlFile.nodes('/rss/channel/item') AS xTable(t);
Related
I am trying to bypass C# to build a google shopping feed directly from SQL Server.
This is what I have for the nested XML body.
DECLARE #XMLBODY XML
SET #XMLBODY = (
SELECT
ID as "ID",
title as "title",
link as "link",
[description] as "description",
image_link as "image_link"
,[Price] as "Price"
,[mpn] as "mpn"
,[brand] as "brand"
,[Condition] as "Condition"
,[availability] as "availability"
,[shipping_weight] as "shipping_weight"
,[google_product_category] as "google_product_category"
,[custom_label_0] as "custom_label_0"
,[custom_label_1] as "custom_label_1"
,[custom_label_2] as "custom_label_2"
,[custom_label_3] as "custom_label_3"
,[custom_label_4] as "custom_label_4" FROM dbo.SmartShoppingFeed
FOR XML PATH ('item'))
SELECT #XMLBODY
And as result, I am getting the following XML (only showing first 2..)
<item>
<ID>22760</ID>
<title>76101 - Product Name A</title>
<link>landingpage2.aspx</link>
<description>body spacers</description>
<image_link>productimage_001.jpg</image_link>
<Price>427.6300</Price>
<mpn>76101AA</mpn>
</item>
<item>
<ID>22760</ID>
<title>76101 - Product Name B</title>
<link>landingpage2.aspx</link>
<description>body spacers</description>
<image_link>productimage_002.jpg</image_link>
<Price>427.6300</Price>
<mpn>76102AA</mpn>
</item>
And what I need as final result is the body with schema, version, and NS before the body and closing tag after the body as follow
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>storename</title>
<link>https://www.storename.com/</link>
<description></description>
<language>en-US</language>
<pubDate>Thu, 25 Jul 2019 20:43:33 GMT</pubDate>
<lastBuildDate>Thu, 25 Jul 2019 20:43:33 GMT</lastBuildDate>
<item>
<ID>22760</ID>
<title>76101 - Product Name A</title>
<link>landingpage2.aspx</link>
<description>body spacers</description>
<image_link>productimage_001.jpg</image_link>
<Price>427.6300</Price>
<mpn>76101AA</mpn>
</item>
<item>
<ID>22760</ID>
<title>76101 - Product Name B</title>
<link>landingpage2.aspx</link>
<description>body spacers</description>
<image_link>productimage_002.jpg</image_link>
<Price>427.6300</Price>
<mpn>76102AA</mpn>
</item>
</channel>
</rss>
I have tried many workarounds to add them statically by casting as string and use concat to combine the head and tail with the body but that didn't work as planned.
Thanks for the help in advance.
You can use XQuery to easily re-shape the final XML as follows:
SQL
DECLARE #XMLBODY XML = '<item>
<ID>22760</ID>
<title>76101 - Product Name A</title>
<link>landingpage2.aspx</link>
<description>body spacers</description>
<image_link>productimage_001.jpg</image_link>
<Price>427.6300</Price>
<mpn>76101AA</mpn>
</item>
<item>
<ID>22760</ID>
<title>76101 - Product Name B</title>
<link>landingpage2.aspx</link>
<description>body spacers</description>
<image_link>productimage_002.jpg</image_link>
<Price>427.6300</Price>
<mpn>76102AA</mpn>a
</item>';
DECLARE #finalXML XML;
SET #finalXML = #XMLBODY.query('<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>storename</title>
<link>https://www.storename.com/</link>
<description></description>
<language>en-US</language>
<pubDate>Thu, 25 Jul 2019 20:43:33 GMT</pubDate>
<lastBuildDate>Thu, 25 Jul 2019 20:43:33 GMT</lastBuildDate>
{
for $item in /item
return $item
}
</channel>
</rss>
');
SELECT #finalXML;
Strictly speaking, Google product feed requires prefixes so the solution may look like this.
DECLARE #XMLBODY XML
with xmlnamespaces('http://base.google.com/ns/1.0' as g,
'http://base.google.com/cns/1.0' as c)
SELECT #XMLBODY = (
SELECT
ID as "g:ID",
title as "title",
link as "link",
[description] as "description",
image_link as "g:image_link"
,[Price] as "g:price"
,[mpn] as "g:mpn"
,[brand] as "g:brand"
,[Condition] as "g:condition"
,[availability] as "g:availability"
,[shipping_weight] as "g:shipping_weight"
,[google_product_category] as "g:google_product_category"
,[custom_label_0] as "c:custom_label_0"
,[custom_label_1] as "c:custom_label_1"
FROM dbo.SmartShoppingFeed
FOR XML PATH ('item'),root('root'))
SELECT #XMLBODY
And then apply great #Yitzhak Khabinsky's solution.
I have a column called MetaXML, which has XML stored inside. I only want to extract information relating to the URLpanel tag. How do I access the node/element down to the URLPanel tag. I also want to separate out the Cap, CaptionText, Height, HeightType, ID and URL (all contained in URLPanel). Is that possible?
Note: I've removed the schema info from the first line...
<DASHBOARD>
<COLUMNS>
<COLUMN Width="19" WidthType="Percent">
<PANELS>
<ACTIONLISTPANEL Cap="8fdd05da-c6b9-41c3-9e4d-5b661c3e134a"
CaptionText="My Action List" Height="14" HeightType="Percent"
ID="CL_Front9.2_c0_r0" />
<PROCESSPANEL Cap="11e934f8-1aed-4fd3-ad95-42049343a390" CaptionText="My
Processes" Height="19" HeightType="Percent" ID="CL_Front9.2_c0_r1">
<APPOBJECTS>
<APPOBJECT AppObjectID="CL_WfMyMattersActList" ID="8a690a0f-268c-
4eb0-8536-6ac09605b7f8" Type="Process" />
<APPOBJECT AppObjectID="CL_ModifyTimeNarrative" ID="d2f320e9-2797-
4631-b63a-5bdcb241d633" Type="Process" />
<APPOBJECT AppObjectID="Invoice Inquiry" ID="7749f30c-acdf-4c09-
b841-60026e274284" Type="Dashboard" />
</APPOBJECTS>
</PROCESSPANEL>
<DASHBOARDENTRY Cap="13d4cd47-a3cf-4222-b03b-932bd8ff6850"
CaptionText="Inquiry" DBID="CliMattInquiry2" Height="50"
HeightType="Percent" ID="CL_Front9.2_c0_r2" />
<REPORTPANEL Cap="9596ced2-76d2-4ebb-a7a3-4f2bd2450fde" CaptionText="My
Details" Height="17" HeightType="Percent" ID="CL_Front9.2_c0_r3">
<VIEWS CurrentViewID="CL_TkprStaticUser">
<VIEW Cap="5f99bd4b-1509-4a65-a54c-07bbc444aceb" CaptionText="My
Details" ReportLayoutID="CL_TkprStaticUser" Type="Report" />
</VIEWS>
</REPORTPANEL>
</PANELS>
</COLUMN>
<COLUMN Width="77" WidthType="Percent">
<PANELS>
<URLPANEL Cap="de940bd4-80f8-47f4-b721-76eed63c650f" CaptionText="Fee
Earner Dashboard" Height="100" HeightType="Percent" ID="CL_Front9.2_c1_r0"
Url="http://ccdc1sql119/ReportServer_SQLR_FINDW_PRD1/Pages/ReportViewer.aspx?%2fDWR%2fMIP+Phase+3%2fMIP_Landing_Indiv&rs:Command=Render&rc:Parameters=Collapsed" />
</PANELS>
</COLUMN>
</COLUMNS>
<SHORTLIST />
</DASHBOARD>
The XML above is quite small, but I cannot seem to extract the URLPanel tag. I've created the following SQL to try to extract the URLPanel tag:
DECLARE #DataID UNIQUEIDENTIFIER
SET #DataID = 'AEFFF874-5980-4340-92C1-ED6B292AA667'
BEGIN
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#TempXML') IS NOT NULL
DROP TABLE #TempXML
DECLARE #X XML
SET #X = (SELECT D.MetaXML AS 'MetaXML'
FROM NxFWKAppObjectData AS D
WHERE NxFWKAppObjectDataID = #DataID)
DECLARE #iX INT
EXEC sp_xml_preparedocument #ix output, #x
CREATE TABLE #TempXML (URLPanel NVARCHAR(MAX))
INSERT INTO #TempXML(URLPanel)
SELECT
URLPanel
FROM
OPENXML(#iX, '//DASHBOARD/COLUMNS/COLUMN/PANELS/URLPANEL', 2)
WITH
(URLPanel NVARCHAR(MAX))
SELECT *
FROM #TempXML AS DT
EXEC sp_xml_removedocument #iX
DROP TABLE #TempXML
END
I would recommend to use the built-in native XQuery support (instead of the legacy OPENXML approach which has its problems with memory leaks etc.).
Given your #X variable - try this:
SELECT
Cap = XC.value('#Cap', 'varchar(50)'),
CaptionText = XC.value('#CaptionText', 'varchar(250)'),
Height = XC.value('#Height', 'int'),
HeightType = XC.value('#HeightType', 'varchar(50)'),
ID = XC.value('#ID', 'varchar(50)'),
Url = XC.value('#Url', 'varchar(500)')
FROM
#X.nodes('/DASHBOARD/COLUMNS/COLUMN/PANELS/URLPANEL') AS XT(XC)
This hopefully should return the bits of data you're looking for.
I am trying to convert XML node values to comma separated values but, getting a
Incorrect syntax near the keyword 'SELECT'.
error message
declare #dataCodes XML = '<Root>
<List Value="120" />
<List Value="110" />
</Root>';
DECLARE #ConcatString VARCHAR(MAX)
SELECT #ConcatString = COALESCE(#ConcatString + ', ', '') + Code FROM (SELECT T.Item.value('#Value[1]','VARCHAR(MAX)') as Code FROM #dataCodes.nodes('/Root/List') AS T(Item))
SELECT #ConcatString AS Result
GO
I tried to follow an article but not sure how to proceed further. Any suggestion is appreciated.
Expectation:
Comma separated values ('120,110') stored in a variable.
Try this;
DECLARE #dataCodes XML = '<Root>
<List Value="120" />
<List Value="110" />
</Root>';
DECLARE #ConcatString VARCHAR(MAX)
SELECT #ConcatString = COALESCE(#ConcatString + ', ', '') + Code
FROM (
SELECT T.Item.value('#Value[1]', 'VARCHAR(MAX)') AS Code
FROM #dataCodes.nodes('/Root/List') AS T(Item)
) as TBL
SELECT #ConcatString AS Result
GO
You just need to add an alias to your sub SQL query.
For future readers, XML data can be extracted into arrays, lists, vectors, and variables for output in comma separated values more fluidly using general purpose languages. Below are open-source solutions using OP's needs taking advantage of XPath.
Python
import lxml.etree as ET
xml = '<Root>\
<List Value="120" />\
<List Value="110" />\
</Root>'
dom = ET.fromstring(xml)
nodes = dom.xpath('//List/#Value')
data = [] # LIST
for elem in nodes:
data.append(elem)
print((", ").join(data))
120, 110
PHP
$xml = '<Root>
<List Value="120" />
<List Value="110" />
</Root>';
$dom = simplexml_load_string($xml);
$node = $dom->xpath('//List/#Value');
$data = []; # Array
foreach ($node as $n){
$data[] = $n;
}
echo implode(", ", $data);
120, 110
R
library(XML)
xml = '<Root>
<List Value="120" />
<List Value="110" />
</Root>'
doc<-xmlInternalTreeParse(xml)
data <- xpathSApply(doc, "//List", xmlGetAttr, 'Value') # LIST
print(paste(data, collapse = ', '))
120, 110
To do this without a variable, you can use the nodes method to convert the xml nodes into a table format with leading commas, then use FOR XML PATH('') to collapse it into a single line of XML, then wrap that in STUFF to convert it to varchar and strip off the initial leading comma:
DECLARE #dataCodes XML = '<Root>
<List Value="120" />
<List Value="110" />
</Root>';
SELECT STUFF(
(
SELECT ', ' + T.Item.value('#Value[1]', 'VARCHAR(MAX)')
FROM #dataCodes.nodes('/Root/List') AS T(Item)
FOR XML PATH('')
), 1, 2, '')
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.
I am trying to send a dbmail with XML code as a body, see my code below showing the same,
declare #xml xml = '<?xml version="1.0"?>
<Order>
<Date>2003/07/04</Date>
<CustomerId>123</CustomerId>
<CustomerName>Acme Alpha</CustomerName>
<Item>
<ItemId> 987</ItemId>
<ItemName>Coupler</ItemName>
<Quantity>5</Quantity>
</Item>
<Item>
<ItemId>654</ItemId>
<ItemName>Connector</ItemName>
<Quantity unit="12">3</Quantity>
</Item>
<Item>
<ItemId>579</ItemId>
<ItemName>Clasp</ItemName>
<Quantity>1</Quantity>
</Item>
</Order>'
--SELECT #xml
declare #bodyprep varchar(max)
select #bodyprep = cast(#xml as varchar(max))
EXEC msdb. dbo.sp_send_dbmail
#profile_name='Profile-A' ,
#recipients ='.com',
#from_address = '.com' ,
#subject = 'test',
#body = #bodyprep
but the mail i receive is unaligned like shown below,
<Order><Date>2003/07/04</Date><CustomerId>123</CustomerId><CustomerName>Acme Alpha</CustomerName><Item><ItemId> 987</ItemId><ItemName>Coupler</ItemName><Quantity>5</Quantity></Item><Item><ItemId>654</ItemId><ItemName>Connector</ItemName><Quantity unit="12">3</Quantity></Item><Item><ItemId>579</ItemId><ItemName>Clasp</ItemName><Quantity>1</Quantity></Item></Order>
Is there a way to format or indent the XML code above ?
I would like to send a formatted code as shown below,
<Order>
<Date>2003/07/04</Date>
<CustomerId>123</CustomerId>
<CustomerName>Acme Alpha</CustomerName>
<Item>
<ItemId> 987</ItemId>
<ItemName>Coupler</ItemName>
<Quantity>5</Quantity>
</Item>
<Item>
<ItemId>654</ItemId>
<ItemName>Connector</ItemName>
<Quantity unit="12">3</Quantity>
</Item>
<Item>
<ItemId>579</ItemId>
<ItemName>Clasp</ItemName>
<Quantity>1</Quantity>
</Item>
</Order>
Thanks
msdb.dbo.sp_send_dbmail has an additional parameter, #body_format = 'HTML', which would allow you to display the XML as you like, once you'd decorated it with the proper HTML markup. That's the only way you can control the appearance of the email body to the level you've specified, i.e. with proper indentation and color-coding.
If you can do without the color-coding, #body_format = 'TEXT' (the default) is fine, but either way you have some work on your hands to get it indented as you indicate.