How to read an attribute of the XML - sql

DECLARE #XmlData xml
SET #XmlData= '<?xml version="1.0" encoding="utf-8" ?>
<ROOT PROCESS_DATE="25-Nov-2009" ROW_COUNT="2" VERIFY_TOTAL="654454.54">
<row rowNumber="1">
<Code1>11111</Code1>
<Code2>AAAA </Code2>
</row>
<row rowNumber="2">
<Code1>2222</Code1>
<Code2>BBBB </Code2>
</row>
</ROOT>'
-- Following query returns the Code1, & Code2 for each row.
SELECT
R.i.query('Code1').value('.', 'nvarchar(8)') AS Code1,
R.i.query('Code2').value('.', 'nvarchar(8)') AS Code2
FROM #XmlData.nodes('/ROOT/row') R(i)
-- Now I want to get the rowNumber attribute of each row in the resultset.
SELECT
R.i.query('#rowNumber') AS rowNumber,
R.i.query('Code1').value('.', 'nvarchar(8)') AS Code1,
R.i.query('Code2').value('.', 'nvarchar(8)') AS Code2
FROM #XmlData.nodes('/ROOT/row') R(i)
-- Above query returns error

DECLARE #x XML ;
SET #x = '<?xml version="1.0" encoding="utf-8" ?>
<ROOT PROCESS_DATE="25-Nov-2009" ROW_COUNT="2" VERIFY_TOTAL="654454.54">
<row rowNumber="1">
<Code1>11111</Code1>
<Code2>AAAA </Code2>
</row>
<row rowNumber="2">
<Code1>2222</Code1>
<Code2>BBBB </Code2>
</row>
</ROOT>' ;
SELECT v.value('.', 'VARCHAR(20)') AS Name
FROM #x.nodes('(/ROOT/row/#*)') x ( v )

I don't have SQL Server handy, but my instincts tell me to try:
R.i.query('.').value('#rowNumber', 'int') AS rowNumber

You can query the attribute with the data() workaround:
R.i.query('data(row/#Name)').value('.','int') AS rowNumber

Related

Add XML attribute in mssql using stored procedure

i want output
<CustomerName>
<Customer id='1'>
<Name>xyz</Name>
</Customer>
<Customer id='2'>
<Name>Abc</Name>
</Customer>
</CustomerName>
for this output i wrote SP
SELECT
'' AS [CustomerName],
(SELECT
Name[Customer/Name]
FOR XML PATH(''), TYPE) AS[CustomerName/Customer]
FOR XML PATH('')
not able to add Id attribute, please help me
Try this:
DECLARE #tblCust TABLE(id INT, CustomerName VARCHAR(100));
INSERT INTO #tblCust VALUES
(1,'xyz')
,(2,'Abc');
SELECT id AS [#id]
,CustomerName AS [Name]
FROM #tblCust
FOR XML PATH('Customer'),ROOT('CustomerName')
This is the result
<CustomerName>
<Customer id="1">
<Name>xyz</Name>
</Customer>
<Customer id="2">
<Name>Abc</Name>
</Customer>
</CustomerName>
SELECT [#id] = t.id, [Name] = t.name
FROM (
VALUES (1, 'name'), (2, 'name2')
) t (id, name)
FOR XML PATH('Customer'), ROOT('CustomerName')

How to using for loop using XQuery to delete xml nodes [duplicate]

This question already has answers here:
Deleting Multiple Nodes in Single XQuery for SQL Server
(2 answers)
Closed 8 years ago.
I have an XML parameter #Xml in SQL Stored procedure like below:
<Root>
<Data>
<Id>1</Id>
<Name>Kevin</Name>
<Des>Des1</Des>
</Data>
<Data>
<Id>2</Id>
<Name>Alex</Name>
<Des>Des2</Des>
</Data>
<Data>
<Id>3</Id>
<Name>Amy</Name>
<Des>Des3</Des>
</Data>
</Root>
now, I want to delete several nodes in this xml, the filter is like this (Id = 2 AND Name = 'Alex') OR (Id = 3 AND Name = 'Amy'), I don't want to use Cursor or something like this, just using one single script to do it, I am try to my best for this, but I can't get the answer, anybody can help me ? Thanks in advance!!!
The output should be :
<Root>
<Data>
<Id>1</Id>
<Name>Kevin</Name>
<Des>Des1</Des>
</Data>
</Root>
PS: the filter is a #table, so, the actually question is , how to remove the specific records in XML which contains in #table?
Id Name
2 Alex
3 Amy
Declare #Xml XML
set #Xml = '<Root>
<Data>
<Id>1</Id>
<Name>Kevin</Name>
<Des>Des1</Des>
</Data>
<Data>
<Id>2</Id>
<Name>Alex</Name>
<Des>Des2</Des>
</Data>
<Data>
<Id>3</Id>
<Name>Amy</Name>
<Des>Des3</Des>
</Data>
</Root>'
create TABLE #tempResult
(
Id Int,
Name Varchar(10)
)
insert into #tempResult
values(2, 'Alex'), (3, 'Amy')
SET #Xml = (
SELECT Node.value('Id[1]','int') AS PId, Node.value('Name[1]','Varchar(10)') AS PName
FROM #Xml.nodes('//Data') AS T(Node)
OUTER APPLY (
SELECT tr.Id, tr.Name
FROM #tempResult tr
WHERE Node.value('Id[1]','int') = tr.Id and Node.value('Name[1]','Varchar(10)') = tr.Name
) a
WHERE a.Id IS NULL
FOR XML PATH(''), TYPE
)
select #Xml
drop table #tempResult
I got results like this
1
Kevin
But I need the the whole xml contains Root node:
<Root>
<Data>
<Id>1</Id>
<Name>Kevin</Name>
<Des>Des1</Des>
</Data>
</Root>
How can I reach this? Any help? I am an new leaner for SQL to XML, please help me !!!
I got the answer, thanks all you guys
declare #xml xml
set #xml = '<Root><Header>123</Header><Data><Id>1</Id><Name>Kevin</Name><Des>Des1</Des></Data><Data><Id>2</Id><Name>Alex</Name><Des>Des2</Des></Data><Data><Id>3</Id><Name>Amy</Name><Des>Des3</Des></Data><Tail>456</Tail></Root>'
--set #xml.modify('delete /Root/Data[(Id[.=1] and Name[.="Kevin"]) or (Id[.=2] and Name[.="Alex"])]')
select #xml
declare #parameter XML
set #parameter = (SELECT Node.value('(Id)[1]', 'Int') AS Id,
Node.value('(Name)[1]', 'Varchar(10)') AS Name
FROM #xml.nodes('Root/Data') TempXML(Node)
WHERE Node.value('(Id)[1]', 'Int') != 3
for xml path('Root'), TYPE)
--select #parameter
declare #sql nvarchar(max)
set #sql = convert(nvarchar(max),
#parameter.query('for $i in (/Root) return concat("(Id[.=",
string($i/Id[1]),
"] and Name[.=""",
string($i/Name[1]),
"""]) or")')
)
set #sql = '['+substring(#sql,0,len(#sql)-2)+']'
set #sql = 'set #xml.modify(''delete /Root/Data'+#sql+''')'
select #sql
exec sp_executesql #sql, N'#xml xml output', #xml output
select #xml
You can shred the xml on the nodes in the root node #xml.nodes('/Root/*') and rebuild it using the XML from the shredded nodes R.X.query('.').
In a where not exists clause you exclude the Data nodes that is present in the temp table.
select R.X.query('.')
from #xml.nodes('/Root/*') as R(X)
where not exists (
select *
from #tempResult as T
where T.Id = R.X.value('(Id/text())[1]', 'int') and
T.Name = R.X.value('(Name/text())[1]', 'varchar(100)') and
R.X.value('local-name(.)', 'varchar(100)') = 'Data'
)
for xml path(''), root('Root'), type
Result:
<Root>
<Header>123</Header>
<Data>
<Id>1</Id>
<Name>Kevin</Name>
<Des>Des1</Des>
</Data>
<Tail>456</Tail>
</Root>
SQL Fiddle

How do I select the node values from the following XML using SQL?

I have the following:
DECLARE #XML XML
SET #XML = '<?xml version="1.0" encoding="utf-8"?>
<member xmlns="http:...xsd" xmlns:xsi="http:...XMLSchema-instance">
<Person>
<Name>Jorge</Name>
<LastName>Bond</LastName>
</Person>
<Person>
<Name>Jorge</Name>
<LastName>Bond</LastName>
</Person>
</member>
I have a table with the following columns:
Member
Person
Name
LastName
How do I go about adding the values from the XML to my table?
If I'm not mistaken I'd have to do a CROSS APPLY but im not sure how to do this.
You can use something like this:
DECLARE #XML XML
SET #XML = '<?xml version="1.0" encoding="utf-8"?>
<member xmlns="http://testxsd" xmlns:xsi="http:...XMLSchema-instance">
<Person>
<Name>Jorge</Name>
<LastName>Bond</LastName>
</Person>
<Person>
<Name>Jorge</Name>
<LastName>Bond</LastName>
</Person>
</member>'
;WITH XMLNAMESPACES(DEFAULT 'http://testxsd')
SELECT
PersonName = XPerson.value('(Name)[1]', 'varchar(50)'),
PersonLastName = XPerson.value('(LastName)[1]', 'varchar(50)')
FROM #XML.nodes('/member/Person') AS XTbl(XPerson)
which will give you an output of:
And of course, if you want to insert that data into a table, you can use:
;WITH XMLNAMESPACES(DEFAULT 'http://testxsd')
INSERT INTO dbo.Person(Name, LastName)
SELECT
PersonName = XPerson.value('(Name)[1]', 'varchar(50)'),
PersonLastName = XPerson.value('(LastName)[1]', 'varchar(50)')
FROM #XML.nodes('/member/Person') AS XTbl(XPerson)

Unable to read data into SQL Server 2005 from an XML file

I am trying to use the following script to read data from an XML file and insert it into a table called TermsTree on SQL Server 2005.
INSERT INTO TermsTree (TermID,ParentID,Name)
SELECT X.TermsTree.query('TermID').value('.', 'INT'),
X.TermsTree.query('ParentID').value('.', 'INT'),
X.TermsTree.query('Name').value('.', 'VARCHAR(2000)')
FROM (
SELECT CAST(x AS XML)
FROM OPENROWSET(
BULK 'C:\Users\MehtabM\Desktop\GetAllTermTree.xml',
SINGLE_BLOB) AS T(x)
) AS T(x)
CROSS APPLY x.nodes('ArrayOfTerm_Child/Term_Child') AS X(TermsTree);
A sample of the XML file is
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfTerm_Child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Term_Child>
<TermID>2021</TermID>
<Name>A. Geographic locations</Name>
<ParentID>0</ParentID>
</Term_Child>
<Term_Child>
<TermID>3602</TermID>
<Name>Oceania</Name>
<ParentID>2021</ParentID>
</Term_Child>
<Term_Child>
<TermID>3604</TermID>
<Name>Australasia</Name>
<ParentID>3602</ParentID>
</Term_Child>
</Term_Child>
</ArrayOfTerm_Child>
http://www.sqlfiddle.com/#!3/18f84/15
declare #xml xml
select #xml='<?xml version="1.0" encoding="utf-8"?>
<ArrayOfTerm_Child xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Term_Child>
<TermID>2021</TermID>
<Name>A. Geographic locations</Name>
<ParentID>0</ParentID>
</Term_Child>
<Term_Child>
<TermID>3602</TermID>
<Name>Oceania</Name>
<ParentID>2021</ParentID>
</Term_Child>
<Term_Child>
<TermID>3604</TermID>
<Name>Australasia</Name>
<ParentID>3602</ParentID>
</Term_Child>
</ArrayOfTerm_Child>'
;WITH XMLNAMESPACES(DEFAULT 'http://tempuri.org/')
SELECT X.TermsTree.query('TermID').value('.', 'INT'),
X.TermsTree.query('ParentID').value('.', 'INT'),
X.TermsTree.query('Name').value('.', 'VARCHAR(2000)')
FROM #xml.nodes('/ArrayOfTerm_Child/Term_Child') X(TermsTree)

Transform XML to Table data using XQuery in SQL Server

Is it possible to achieve the following table from of output using XQuery in SQL Server
Edit: A change in my requirement, Consider i have a table which stores the below xml and also UserID
DECLARE #XML xml
set #XML = '<Security>
<FiscalYear Name="2012">
<Country Id="204">
<State Id="1">
<City Id="10"></City>
</State>
<State Id="2">
<City Id="20"></City>
<City Id="30"></City>
</State>
<State Id ="3"></State>
</Country >
</FiscalYear>
</Security>'
CREATE TABLE #tmp_user
(UserID INT,SecurityXML XML)
INSERT INTO #tmp_user
( UserID, SecurityXML )
VALUES ( 1,
#XML
)
Now how can i get a o/p like
Output:
UserID StateID CityID
1 1 10
1 2 20
1 2 30
1 3 0
Is it possible to achieve?
I modified your XML a bit because it was invalid. Change the end tag </Subsidiary> to </Country>.
declare #XML xml
set #XML =
'<Security>
<FiscalYear Name="2012">
<Country Id="204">
<State Id="1">
<City Id="10"></City>
</State>
<State Id="2">
<City Id="20"></City>
<City Id="30"></City>
</State>
<State Id ="3"></State>
</Country>
</FiscalYear>
</Security>'
select S.N.value('#Id', 'int') as StateID,
coalesce(C.N.value('#Id', 'int'), 0) as CityID
from #XML.nodes('/Security/FiscalYear/Country/State') as S(N)
outer apply S.N.nodes('City') as C(N)
A version using a table instead of XML variable
select T.UserID,
S.N.value('#Id', 'int') as StateID,
coalesce(C.N.value('#Id', 'int'), 0) as CityID
from #tmp_user as T
cross apply T.SecurityXML.nodes('/Security/FiscalYear/Country/State') as S(N)
outer apply S.N.nodes('City') as C(N)