Query XML value in sql - sql-server

I need to get some information from XML in SQL Server 2008, but I cannot even get basic attribute from it. All samples that I tried failed. Table name is Item, xml column name is Data.
Simplified xml looks like this:
<AnchoredXml xmlns="urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008" SchemaWriteVersion="2">
<Key ScopeClass="Global">
<SchemaId Namespace="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" ElementName="Topology" />
<AuthorityId Class="Host" InstanceId="00000000-0000-0000-0000-000000000000" />
</Key>
<Dictionary Count="1">
<Item>
<Key />
<Value Signature="a3502dd0-8c16-4023-9eea-30ea1c7a3a2b">
<Topology xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008">
<Services>
<Service RoleVersion="1" ServiceVersion="6" Type="Microsoft.Rtc.Management.Deploy.Internal.ServiceRoles.FileStoreService">
<ServiceId SiteId="1" RoleName="FileStore" Instance="1" />
<DependsOn />
<InstalledOn>
<ClusterId SiteId="1" Number="1" />
</InstalledOn>
<Ports xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.ServiceRoles.2008" />
<FileStoreService xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.ServiceRoles.2008" ShareName="lyncShare" />
</Service>
</Services>
</Topology>
</Value>
</Item>
</Dictionary>
</AnchoredXml>
I need to read information in AnchoredXml/Key/SchemaId/#NameSpace to select the right xml (there are more rows). Sample xml above is the right one. And after that I need to find the right service with
Type="Microsoft.Rtc.Management.Deploy.Internal.ServiceRoles.FileStoreService"
where is FileStoreService/#ShareName that I need.
I've tried to print the Namespace attributte for the start, but no sample code is working.
A few tries:
SELECT c.p.value('(#Namespace)[1]', 'varchar(50)') as 'Nmspace'
FROM Item
CROSS APPLY Data.nodes('/AnchoredXml/Key/SchemaId') c(p)
returns empty result set
SELECT Data.value('(/AnchoredXml/Key/SchemaId/#Namespace)[1]', 'varchar(50)')
FROM Item
returns NULL for all rows
SELECT
It.Data.exist('/AnchoredXml/Key/SchemaId[#Namespace="Microsoft.Rtc.Management.Deploy.Topology.2008"]')
FROM [xds].[dbo].[Item] AS It
returns 0's for all rows also without quotes ("")
A working sample code to get at least attribute test would be maybe sufficient and I would figure out the rest.
Could you please help me find errors in my queries or maybe identify some other problem?
Thanks

You're ignoring all the XML namespaces in your XML document! You need to pay attention to those and respect them!
There are XML namespaces on:
the root node <AnchoredXml>
(XML namespace: urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008)
the subnode <Topology>
(XML ns: urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008)
the subnode <FileStoreService>
(XML ns: urn:schema:Microsoft.Rtc.Management.Deploy.ServiceRoles.2008)
Try this:
-- respect the XML namespaces!!
;WITH XMLNAMESPACES(DEFAULT 'urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008',
'urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008' AS t,
'urn:schema:Microsoft.Rtc.Management.Deploy.ServiceRoles.2008' AS fss)
SELECT
ShareName = Data.value('(/AnchoredXml/Dictionary/Item/Value/t:Topology/t:Services/t:Service/fss:FileStoreService/#ShareName)[1]', 'varchar(50)')
FROM
dbo.Item
In my case, this returns:
ShareName
-----------
lyncShare

Related

Typed XML Update in SQL Server table

I have 3rd party table with XML column and I need to change the recipient value in the value if the key\string = 'recipient'. Here is a slice of the original XML with 2 items:
DECLARE #myDoc XML
SET #myDoc = '<Root>
<item>
<key>
<string>subject</string>
</key>
<value>
<anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="q1:string">test subject</anyType>
</value>
</item>
<item>
<key>
<string>recipient</string>
</key>
<value>
<anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" xmlns:p5="http://www.w3.org/2001/XMLSchema-instance" p5:type="q1:string">prodops#company.com</anyType>
</value>
</item>
</Root>'
SET #myDoc.modify('
declare namespace q1="http://www.w3.org/2001/XMLSchema"; declare namespace p5="http://www.w3.org/2001/XMLSchema-instance";
replace value of (/q1:Root/q1:item/q1:value/p5:type="q1:string")[1]
with ("devops#company.com")
')
SELECT #myDoc
I have kind of hacked my way to this point - XML is not my strong suit. Based on BOL, I need to do something with namespace in the modify()? Right? I'm missing an if statement I am sure but just a mystery as to how to de-reference that value for recipient. Someone has done this before - I am sure. The goal is to incorporate into a post-restore script after refreshing production data to test.
Note that this fails as-is with
Msg 2337, Level 16, State 1, Line 125
XQuery [modify()]: The target of 'replace' must be at most one node, found 'xs:boolean ?'"
You need to specify text() to replace the inner text of a node. You also need to reference the anyType node, which you have not.
By the looks of things, none of the relevant nodes actually use the namespaces, so we don't need them at all.
SET #myDoc.modify('
replace value of (/Root/item[key[string[text()="recipient"]]]/value/anyType/text())[1]
with ("devops#company.com")
');
Explanation:
Descend to /Root, no namespace needed
Descend to /item[ with a predicate...
... must have key[ node ...
... which has string[ node ...
... which has inner text()="recipient"]]]
Back to the original item we descend /value then /anyType then inner /text()
All bracketed to [1] to ensure a single node
The title of the question specifies "Typed XML Update in SQL Server table".
The provided XML is not bound by any XSD schema. That's why that XML is not typed. A real typed XML is updated differently.
Please try the following solution. It has the following:
Somewhat simpler XPath predicate expression.
Using SQL variable for a new value.
All credit goes to #Charlieface.
SQL
DECLARE #myDoc XML =
N'<Root>
<item>
<key>
<string>subject</string>
</key>
<value>
<anyType xmlns:q1="http://www.w3.org/2001/XMLSchema"
xmlns:p5="http://www.w3.org/2001/XMLSchema-instance"
p5:type="q1:string">test subject</anyType>
</value>
</item>
<item>
<key>
<string>recipient</string>
</key>
<value>
<anyType xmlns:q1="http://www.w3.org/2001/XMLSchema"
xmlns:p5="http://www.w3.org/2001/XMLSchema-instance"
p5:type="q1:string">prodops#company.com</anyType>
</value>
</item>
</Root>';
DECLARE #anyType VARCHAR(30) = 'devops#company.com';
SET #myDoc.modify('
replace value of (/Root/item[key/string/text()="recipient"]/value/anyType/text())[1]
with (sql:variable("#anyType"))
');
-- test
SELECT #myDoc;

Insert XML child node to SQL table

I've got an XML file like this and I'm working with SQL 2014 SP2
<?xml version='1.0' encoding='UTF-8'?>
<gwl>
<version>123456789</version>
<entities>
<entity id="1" version="123456789">
<name>xxxxx</name>
<listId>0</listId>
<listCode>Oxxx</listCode>
<entityType>08</entityType>
<createdDate>03/03/1993</createdDate>
<lastUpdateDate>05/06/2011</lastUpdateDate>
<source>src</source>
<OriginalSource>o_src</OriginalSource>
<aliases>
<alias category="STRONG" type="Alias">USCJSC</alias>
<alias category="WEAK" type="Alias">'OSKOAO'</alias>
</aliases>
<programs>
<program type="21">prog</program>
</programs>
<sdfs>
<sdf name="OriginalID">9876</sdf>
</sdfs>
<addresses>
<address>
<address1>1141, SYA-KAYA STR.</address1>
<country>RU</country>
<postalCode>1234</postalCode>
</address>
<address>
<address1>90, MARATA UL.</address1>
<country>RU</country>
<postalCode>1919</postalCode>
</address>
</addresses>
<otherIds>
<childId>737606</childId>
<childId>737607</childId>
</otherIds>
</entity>
</entities>
</gwl>
I made a script to insert data from the XML to a SQL table. How can I insert child node into a table? I think I should replicate the row for each new child node but i don't know the best way to proceed.
Here is my SQL code
DECLARE #InputXML XML
SELECT #InputXML = CAST(x AS XML)
FROM OPENROWSET(BULK 'C:\MyFiles\sample.XML', SINGLE_BLOB) AS T(x)
SELECT
product.value('(#id)[1]', 'NVARCHAR(10)') id,
product.value('(#version)[1]', 'NVARCHAR(14)') ID
product.value('(name[1])', 'NVARCHAR(255)') name,
product.value('(listId[1])', 'NVARCHAR(9)')listId,
product.value('(listCode[1])', 'NVARCHAR(10)')listCode,
product.value('(entityType[1])', 'NVARCHAR(2)')entityType,
product.value('(createdDate[1])', 'NVARCHAR(10)')createdDate,
product.value('(lastUpdateDate[1])', 'NVARCHAR(10)')lastUpdateDate,
product.value('(source[1])', 'NVARCHAR(15)')source,
product.value('(OriginalSource[1])', 'NVARCHAR(50)')OriginalSource,
product.value('(aliases[1])', 'NVARCHAR(50)')aliases,
product.value('(programs[1])', 'NVARCHAR(50)')programs,
product.value('(sdfs[1])', 'NVARCHAR(500)')sdfs,
product.value('(addresses[1])', 'NVARCHAR(50)')addresses,
product.value('(otherIDs[1])', 'NVARCHAR(50)')otherIDs
FROM #InputXML.nodes('gwl/entities/entity') AS X(product)
You have a lot of different children here...
Just to show the principles:
DECLARE #xml XML=
N'<gwl>
<version>123456789</version>
<entities>
<entity id="1" version="123456789">
<name>xxxxx</name>
<listId>0</listId>
<listCode>Oxxx</listCode>
<entityType>08</entityType>
<createdDate>03/03/1993</createdDate>
<lastUpdateDate>05/06/2011</lastUpdateDate>
<source>src</source>
<OriginalSource>o_src</OriginalSource>
<aliases>
<alias category="STRONG" type="Alias">USCJSC</alias>
<alias category="WEAK" type="Alias">''OSKOAO''</alias>
</aliases>
<programs>
<program type="21">prog</program>
</programs>
<sdfs>
<sdf name="OriginalID">9876</sdf>
</sdfs>
<addresses>
<address>
<address1>1141, SYA-KAYA STR.</address1>
<country>RU</country>
<postalCode>1234</postalCode>
</address>
<address>
<address1>90, MARATA UL.</address1>
<country>RU</country>
<postalCode>1919</postalCode>
</address>
</addresses>
<otherIds>
<childId>737606</childId>
<childId>737607</childId>
</otherIds>
</entity>
</entities>
</gwl>';
-The query will fetch some values from several places.
--It should be easy to get the rest yourself...
SELECT #xml.value('(/gwl/version/text())[1]','bigint') AS [version]
,A.ent.value('(name/text())[1]','nvarchar(max)') AS [Entity_Name]
,A.ent.value('(listId/text())[1]','int') AS Entity_ListId
--more columns taken from A.ent
,B.als.value('#category','nvarchar(max)') AS Alias_Category
,B.als.value('text()[1]','nvarchar(max)') AS Alias_Content
--similar for programs and sdfs
,E.addr.value('(address1/text())[1]','nvarchar(max)') AS Address_Address1
,E.addr.value('(country/text())[1]','nvarchar(max)') AS Address_Country
--and so on
FROM #xml.nodes('/gwl/entities/entity') A(ent)
OUTER APPLY A.ent.nodes('aliases/alias') B(als)
OUTER APPLY A.ent.nodes('programs/program') C(prg)
OUTER APPLY A.ent.nodes('sdfs/sdf') D(sdfs)
OUTER APPLY A.ent.nodes('addresses/address') E(addr)
OUTER APPLY A.ent.nodes('otherIds/childId') F(ids);
The idea in short:
We read non-repeating values (e.g. version) from the xml variable directly
We use .nodes() to return repeating elements as derived sets.
We can use a cascade of .nodes() to dive deeper into repeating child elements by using a relativ Xpath (no / at the beginning).
You have two approaches:
Read the XML like above into a staging table (simply by adding INTO #tmpTable before FROM) and proceed from there (will need one SELECT ... GROUP BY for each type of child).
Create one SELECT per type of child, using only one of the APPLY lines and shift the data into specific child tables.
I would tend to the first one.
This allows to do some cleaning, generate IDs, check for business rules, before you shift this into the target tables.

Retrieve an element value from an XML string during an SQL select request

I'm querying a table T which has a string column StrXML that has XML text stored in it. Here's an example of the XML stored:
<Sequence mc:Ignorable="sap sads" DisplayName="Post Processing"
sap:VirtualizedContainerService.HintSize="424,318"
mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces"
xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006
xmlns:mee="clr-namespace:MatX.eRP.Entities;assembly=eRP.Entities"
xmlns:mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities"
xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities"
xmlns:sads="http://schemas.microsoft.com/netfx/2010/xaml/activities/debugger"
xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mepa:BasicOperation Description="Traitement Thermique" DisplayName="HeatTreatment" Guid="82800b59-e181-4a93-b483-7e2cd9b14827" sap:VirtualizedContainerService.HintSize="402,154" Scope="Build">
<mepa:BasicOperation.MeasurementDescriptions>
<scg:List x:TypeArguments="mee:MeasurementDescription" Capacity="0" />
</mepa:BasicOperation.MeasurementDescriptions>
</mepa:BasicOperation>
<mepa:BasicOperation Description="Finition manuelle" DisplayName="Manual Finishing" Guid="cd64be75-6968-47fe-8aac-93a4fdf37892">
<mepa:BasicOperation.MeasurementDescriptions>
<scg:List x:TypeArguments="mee:MeasurementDescription" Capacity="4">
<mee:MeasurementDescription Max="{x:Null}" Min="{x:Null}" Guid="7c1a37f1-f39d-4ed3-8048-6b0a266c70b9" IsRequired="False" Name="MesureMF1" Type="Double" />
<mee:MeasurementDescription Max="{x:Null}" Min="{x:Null}" Guid="a21b0c0d-dfff-4237-9975-4179bcefe7c2" IsRequired="False" Name="MesureMF2" Type="Double" />
</scg:List>
</mepa:BasicOperation.MeasurementDescriptions>
</mepa:BasicOperation>
</Sequence>
In my select request on table T, I want to only show the Description value for which the Guid="82800b59-e181-4a93-b483-7e2cd9b14827".
How can I do that?
In a comment I mentioned already, that one of your namespaces is missing the final ". This is a big problem, if it's not just a copy-and-paste issue... (not well formed)
XML should not be stored in a string column (slow and dangerous!). If you database does not support XML natively the XML should at least be checked.
You did not mention the actual RDBMS, but the XQuery-principles should be the same (however your RDBMS deals with XQuery actually).
The simple approach is this XQuery (fetch any <BasicOperation>, wherever it is placed, and filter for the given GUID)
//*:BasicOperation[#Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/#Description
With SQL-Server you can try this
SELECT CAST(T.StrXML AS XML).value(N'(//*:BasicOperation[#Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/#Description)[1]',N'nvarchar(max)')
The more specific (and recommended) approach is this:
declare namespace dflt="http://schemas.microsoft.com/netfx/2009/xaml/activities";
declare namespace mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities";
dflt:Sequence/mepa:BasicOperation[#Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/#Description
Again - with SQL-Server - you might try this:
SELECT CAST(T.StrXML AS XML).value(N'declare namespace dflt="http://schemas.microsoft.com/netfx/2009/xaml/activities";
declare namespace mepa="clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities";
(dflt:Sequence/mepa:BasicOperation[#Guid="82800b59-e181-4a93-b483-7e2cd9b14827"]/#Description)[1]',N'nvarchar(max)')
If the GUID-value is variable SQL-Server would allow you to pass the value in from a variable declared outside. Read about sql:variable() and sql:column().
UPDATE
You can use lower-case() to get a secure comparison:
DECLARE #xml XML=
'<root>
<a guid="82800b59-e181-4a93-b483-7e2cd9b14827" />
<a guid="82800B59-E181-4A93-B483-7E2CD9B14827" />
</root>';
DECLARE #guid UNIQUEIDENTIFIER='82800B59-E181-4A93-B483-7E2CD9B14827';
SELECT #xml.query(N'/root/a[lower-case(#guid)=lower-case(sql:variable("#guid"))]')
Try something like this, assuming this is for SQL Server:
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.microsoft.com/netfx/2009/xaml/activities',
'clr-namespace:MatX.eRP.PostProcessing.Activities;assembly=PostProcessing.Activities' AS mepa)
SELECT
T.X.value('#Description', 'varchar(100)') AS JobTitle
FROM
#XTable
CROSS APPLY
XmlData.nodes('/Sequence/mepa:BasicOperation') AS T(X)
WHERE
T.X.value('#Guid','varchar(50)') = '82800b59-e181-4a93-b483-7e2cd9b14827'

SQL Query values out of XML using

I can't figure out what I'm doing wrong. I have XML stored in a table column as text. I'm taking the ID, and the XML text and querying it into a temp table that stores the XML as XML type.
Each Order in the XML has multiple licenses in it that I need to pull out and create a new table with OrderID and License ID. But I can't tell what I'm doing wrong.
So, I'm trying to start basic but I can't seem to even just get the Account Info from the first Node.
The XML looks like this:
<ns1:OrderFromCRM xmlns:ns1="http://company.com/licensing/neworder/v2">
<ns1:AccountInfo Name="Company Name" AccountId="A012345" />
<ns1:OrderInfo CRMOrderId="S147360" Date="2/23/2017 12:00:00 AM" ffEmail="emailaddress.#gmail.com" >
<ns1:Licensing>
<ns1:Foundations>
<ns1:Foundation LicenseId="L012345678" Action="Create" Environment="Production" Type="Enterprise">
<Metadata>
<AllowedInstances>999</AllowedInstances>
</Metadata>
</ns1:Foundation>
<ns1:Foundation LicenseId="L012345698" Action="Create" Environment="Production" Type="Enterprise">
<Metadata>
<AllowedInstances>999</AllowedInstances>
</Metadata>
</ns1:Foundation>
</ns1:Foundations>
<ns1:Licenses Type="Create">
<ns1:License LicenseId="L0123451234" ProductFamily="Fam1" Product="EStudio" LicenseType="Perpetual" StartDate="2017-02-23" ExpiryDate="2017-12-18" MaintenanceExpiryDate="2017-12-18">
<ns1:Capabilities>
<ns1:Capability Name="T1" />
<ns1:Capability Name="Q1" />
<ns1:Capability Name="B1" />
</ns1:Capabilities>
</ns1:License>
<ns1:License LicenseId="L333356675" ProductFamily="Fam1" Product="EStudio" LicenseType="Perpetual" StartDate="2017-02-23" ExpiryDate="2017-12-18" MaintenanceExpiryDate="2017-12-18">
<ns1:Capabilities>
<ns1:Capability Name="T1" />
<ns1:Capability Name="Q1" />
<ns1:Capability Name="B1" />
</ns1:Capabilities>
</ns1:License>
The SQL I wrote is:
CREATE TABLE #demoData
(
ActivationCode NVARCHAR(100) NOT NULL,
OrderXMLText XML
)
SELECT OrderId, OrderXMLText.value('(/OrderFromCRM/AccountInfo)[1]', 'varchar(30)')
FROM #DEMODATA
I mentioned I need the OrderID and the LicenseId but even with this, I can't get anything. Am I on right track? First, what am I missing? Second, once this is formatted correctly, how do I get the nested LicenseIds in the XML?
Thanks so much for any help. I've been trying to make this work for a couple days
You’re missing the namespace so the query isn’t matching the xml, therefore it doesn’t find the elements you’re querying.
Add
;WITH XMLNAMESPACES
https://learn.microsoft.com/en-us/sql/t-sql/xml/with-xmlnamespaces
Assuming you have a complete, valid XML document in your table (the one you're showing is lacking several closing tags), then you could try something like this:
;WITH XMLNAMESPACES('http://company.com/licensing/neworder/v2' AS ns1)
SELECT
ActivationCode,
CRMOrderId = XC.value('#CRMOrderId', 'varchar(100)'),
FoundationsLicenseId = xcf.value('#LicenseId', 'varchar(50)'),
LicensesLicenseId = xcl.value('#LicenseId', 'varchar(50)')
FROM
#demoData
CROSS APPLY
OrderXMLText.nodes('/ns1:OrderFromCRM/ns1:OrderInfo') AS XT(XC)
CROSS APPLY
XC.nodes('ns1:Licensing/ns1:Foundations/ns1:Foundation') AS XTF(XCF)
CROSS APPLY
XC.nodes('ns1:Licensing/ns1:Licenses/ns1:License') AS XTL(XCL)
First of all, you need to include and respect the XML namespace in your XQuery - that's what I do with the WITH XMLNAMESPACES() directive.
Next, you need to use .nodes() to get a list of XML fragments for each <OrderInfo> node, which is located below the root node (<OrderFromCRM>). This is the first CROSS APPLY. This returns a list of XML fragments, one for each <OrderInfo> node.
Then you need to reach into these XML fragments, and again use CROSS APPLY with the .nodes() function to get a list of the <Foundation> elements (contained in the <Licensing>/<Foundations> subtree to get the license Id's from those nodes. In addition, you need a second CROSS APPLY to get all the <License> subnodes under <Licensing>/<Licenses> to get those LicenseId attributes.
That should return an output something like:
Hope this helps you some!

Building an XML output using XML EXPLICIT in SQL Server 2014

I have nearly accomplished what I need, but am missing one last thing. I have 2 tables being joined to create an XML output. I need elements of both tables to be used in the same SELECT statement, but am having trouble making that work. This code is what I have:
SELECT
1 as Tag,
0 as Parent,
RTRIM(dbo.DataItemInfo.DataItem) as [DataItem!1!name]
--RTRIM(dbo.DataItemInfo.DataItem) as [dbo.DataSchedule.DataItemValue!1!]
FROM
dbo.DataItemInfo
INNER JOIN
dbo.DataSchedule
ON dbo.DataSchedule.SignID = dbo.DataItemInfo.SignID
AND dbo.DataSchedule.SignID=#ParamSignID
AND dbo.DataSchedule.ScheduleID = dbo.DataItemInfo.ScheduleID
FOR XML EXPLICIT, ROOT('DataItems')
Where the commented out section is one of the things I tried. At the moment, it produces the output:
<DataItems>
<DataItem name="Test1" />
<DataItem name="Test2" />
<DataItem name="Test3" />
<DataItem name="Test4" />
<DataItem name="Test5" />
</DataItems>
But I want:
<DataItems>
<DataItem name="Test1">ValFromScheduleTableHere<DataItem/>
<DataItem name="Test2">ValFromScheduleTableHere<DataItem/>
<DataItem name="Test3">ValFromScheduleTableHere<DataItem/>
<DataItem name="Test4">ValFromScheduleTableHere<DataItem/>
<DataItem name="Test5">ValFromScheduleTableHere<DataItem/>
</DataItems>
I know how to populate the "ValFromScheduleTableHere" from the original table, but not from a second table. Thanks for the help.
FOR XML PATH syntax is easier and you can get the desired result with this SQL.
SELECT
(
SELECT
RTRIM(dbo.DataItemInfo.DataItem) as 'DataItem/#name'
DataSchedule.DataitemValue as 'DataItem'
FROM
dbo.DataItemInfo
INNER JOIN
dbo.DataSchedule
ON dbo.DataSchedule.SignID = dbo.DataItemInfo.SignID
AND dbo.DataSchedule.SignID=#ParamSignID
AND dbo.DataSchedule.ScheduleID = dbo.DataItemInfo.ScheduleID
FOR XML PATH(''), TYPE
)
FOR XML PATH(''), ROOT('DataItems')
I realize this has been answered and even that EXPLICIT mode is no longer being used, but I happened to figure it out so I thought I would share. For better or worse, you were very close. The column name for the field to be the entity value was missing the "directive" portion, which is the 4th (and optional) part of the funky column name !-convention. You needed !xml as the last part, and of course to have adjusted what is in the RTRIM and the rest of the alias, which would have looked like:
RTRIM(DataSchedule.DataItemValue) as [DataItem!1!!xml]
Anyone can test the theory with the following (I aligned the column aliases to more easily see the difference in the 3rd alias):
SELECT 1 AS [Tag],
0 AS [Parent],
RTRIM(so.[type]) AS [Object!1!Type],
so.create_date AS [Object!1!CreateDate],
so.[name] AS [Object!1!!xml]
FROM sys.objects so
FOR XML EXPLICIT, ROOT('Objects');
Output:
<Objects>
<Object Type="S" CreateTate="2014-02-20T20:48:34.573">sysrscols</Object>
<Object Type="S" CreateTate="2009-04-13T12:59:05.513">sysrowsets</Object>
<Object Type="S" CreateTate="2014-02-20T20:48:34.807">sysclones</Object>
<Object Type="S" CreateTate="2009-04-13T12:59:05.500">sysallocunits</Object>
<Object Type="S" CreateTate="2003-04-08T09:13:37.267">sysfiles1</Object>
...
</Objects>
For more info, please see the following MSDN page: Use EXPLICIT Mode with FOR XML

Resources