I have the following XML and I want to extract the FieldValue using SQL. How can I do this?
<Field Group="Annuitant">
<FieldName>Contract Number</FieldName>
<FieldValue>TR13116544</FieldValue>
</Field>
Thanks
DECLARE #xml XML=
'<Field Group="Annuitant">
<FieldName>Contract Number</FieldName>
<FieldValue>TR13116544</FieldValue>
</Field>';
--the lazy approach
SELECT #xml.value('(//FieldValue)[1]','varchar(50)')
--Better
SELECT #xml.value('(/Field/FieldValue)[1]','varchar(50)')
--This is, what you should do: Be as specific as possible...
SELECT #xml.value('(/Field/FieldValue/text())[1]','varchar(50)')
If there are - what I assume - are several <Field> elements and you need to pick the rigth one, you can do something like this:
DECLARE #name VARCHAR(100)='Contract Number';
SELECT #xml.value('(/Field[(FieldName/text())[1]=sql:variable("#name")]/FieldValue/text())[1]','varchar(50)')
Hint: Your question is not very clear, that needs a lot of guessing on my side. For your next question I ask you to be more specific.
Sample code:
DECLARE #MyXML XML
SET #MyXML ='<SampleXML>
<Fruits>
<Fruits1>Apple</Fruits1>
<Fruits2>Pineapple</Fruits2>
</Fruits>
</SampleXML>'
SELECT
a.b.value('Fruits[1]/Fruits1[1]','varchar(10)') AS Fruits1,
a.b.value('Fruits[1]/Fruits2[1]','varchar(10)') AS Fruits2
FROM #MyXML.nodes('SampleXML') a(b)
In oracle you can do the following:
WITH TABL (FIELD) AS (
select xmltype('<Field Group="Annuitant">
<FieldName>Contract Number</FieldName>
<FieldValue>TR13116544</FieldValue>
</Field>') from dual
)
SELECT
EXTRACTVALUE(FIELD,'/Field/FieldName') AS FIELDNAME,
EXTRACTVALUE(field,'/Field/FieldValue') AS FieldValue
FROM TABL ;
Related
Have a table called UserRequest and one column of the is XML type (column name is RequestXML). The values in RequestXML will be something like this:
<MyRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/">
<transfer>
<Field>
<fieldId>12323</fieldId>
<FieldDetails>
<RequestInfoField>
<requestDecs>Test</requestDecs>
<reqDate>01/01/2021</reqDate>
</RequestInfoField>
<identifierKey>45638</identifierKey>
</FieldDetails>
</Field>
</transfer>
</MyRequest>
Using the following SQL query to retrieve the XML node value of identifierKey, but the query is always returning an empty string :
select
T.RequestXML.query('MyRequest/transfer/Field/FieldDetails/identifierKey') As identifierKey, *
from UserRequest T
You haven't declared your (default) namespace in your SQL:
WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/')
SELECT UR.RequestXML.query('MyRequest/transfer/Field/FieldDetails/identifierKey') As identifierKey,
*
FROM dbo.UserRequest UR;
If you, however, explicitly want the value of identifierKey use value, not query.
WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/')
SELECT UR.RequestXML.value('(MyRequest/transfer/Field/FieldDetails/identifierKey)[1]','int') AS identifierKey
*
FROM dbo.UserRequest UR;
db<>fiddle
Like this:
declare #doc xml = '<MyRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/">
<transfer>
<Field>
<fieldId>12323</fieldId>
<FieldDetails>
<RequestInfoField>
<requestDecs>Test</requestDecs>
<reqDate>01/01/2021</reqDate>
</RequestInfoField>
<identifierKey>45638</identifierKey>
</FieldDetails>
</Field>
</transfer>
</MyRequest>';
WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/')
SELECT T.RequestXML.value('(/MyRequest/transfer/Field/FieldDetails/identifierKey)[1]','int') As identifierKey, *
FROM (values(#doc)) T(RequestXML);
I have an XML file in a format similar to:
<XML>
<Field1>100</Field1>
<Field2>200</Field2>
<Field3>300</Field3>
<Test>400</Test>
</XML>
I need to write a query that will get all of the element values that start with Field. So given the XML above the result should be
FieldVal
--------
100
200
300
I've tried the following but it does not work:
Select
xc.value('text()', 'int')
From
#XMLData.nodes('/XML/[starts-with(name(), ''Field'')]') As xt(xc)
NOTE: I am well aware that this task could be easily done if I reformatted my XML but unfortunately I have no control over the format of the XML.
One way is
declare #XMLData xml ='<XML>
<Field1>100</Field1>
<Field2>200</Field2>
<Field3>300</Field3>
<Test>400</Test>
</XML>'
Select
xc.value('.', 'int')
From #XMLData.nodes('/XML/*') As xt(xc)
WHERE xc.value('local-name(.)', 'varchar(50)') LIKE 'Field%'
Prefix name with special character and check contains instead.
declare #x xml ='<XML>
<Field1>100</Field1>
<Field2>200</Field2>
<Field3>300</Field3>
<Test>400</Test>
</XML>';
select t.n.value('.','varchar(100)')
from #x.nodes ('XML/*[contains(concat("$",local-name()),"$Field")]') t(n);
I think it's this what you are looking for:
DECLARE #xml XML=
'<XML>
<Field1>100</Field1>
<Field2>200</Field2>
<Field3>300</Field3>
<Test>400</Test>
</XML>';
SELECT Fld.value('.','int') AS FieldOnly
FROM #xml.nodes('/XML/*[substring(local-name(.),1,5)="Field"]') AS A(Fld)
Just because of the discussion in comments:
DECLARE #fldName VARCHAR(100)='Field';
SELECT Fld.value('.','int') AS FieldOnly
FROM #xml.nodes('/XML/*[substring(local-name(.),1,string-length(sql:variable("#fldName")))=sql:variable("#fldName")]') AS A(Fld)
Change the first line to "Test" (case sensitive!), and you'd get just the one row with 400...
Can anybody please help me with the below xml. I need extract all the xml values like below.
AwarYear Comments FieldCode FieldNumber Key Value
AY2013-14 AAI: Adjusted Available Income AAI 306 Blank None Calculated
Here is the sample XML.
<SchemaType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/process">
<AwardYear>AY2013_14</AwardYear>
<Fields>
<FieldSchema>
<Comments>AAI: Adjusted Available Income</Comments>
<DbLocation>IsirData</DbLocation>
<FieldCode>AAI</FieldCode>
<FieldNumber>306</FieldNumber>
<ReportDisplay>Data</ReportDisplay>
<ValidContent>
<ValidValueContent xmlns:d5p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d5p1:KeyValueOfstringstring>
<d5p1:Key>Blank</d5p1:Key>
<d5p1:Value>None calculated</d5p1:Value>
</d5p1:KeyValueOfstringstring>
</ValidValueContent>
</ValidContent>
</FieldSchema>
</Fields>
</SchemaType>
Please do the need full. Thanks in advance.
Assuming you have your XML in a table inside an XML column like this:
DECLARE #XmlTable TABLE (ID INT NOT NULL, XMLDATA XML)
INSERT INTO #XmlTable VALUES(1, '<SchemaType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/process">
<AwardYear>AY2013_14</AwardYear>
<Fields>
<FieldSchema>
<Comments>AAI: Adjusted Available Income</Comments>
<DbLocation>IsirData</DbLocation>
<FieldCode>AAI</FieldCode>
<FieldNumber>306</FieldNumber>
<ReportDisplay>Data</ReportDisplay>
<ValidContent>
<ValidValueContent xmlns:d5p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d5p1:KeyValueOfstringstring>
<d5p1:Key>Blank</d5p1:Key>
<d5p1:Value>None calculated</d5p1:Value>
</d5p1:KeyValueOfstringstring>
</ValidValueContent>
</ValidContent>
</FieldSchema>
</Fields>
</SchemaType>')
then you can use this T-SQL statement to fetch the values:
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/process',
'http://schemas.microsoft.com/2003/10/Serialization/Arrays' AS ns1)
SELECT
AwardYear = XmlData.value('(SchemaType/AwardYear)[1]', 'varchar(25)'),
Comments = XmlData.value('(SchemaType/Fields/FieldSchema/Comments)[1]', 'varchar(50)'),
FieldCode = XmlData.value('(SchemaType/Fields/FieldSchema/FieldCode)[1]', 'varchar(10)'),
FieldNumber = XmlData.value('(SchemaType/Fields/FieldSchema/FieldNumber)[1]', 'int'),
[Key] = XmlData.value('(SchemaType/Fields/FieldSchema/ValidContent/ValidValueContent/ns1:KeyValueOfstringstring/ns1:Key)[1]', 'varchar(10)'),
[Value] = XmlData.value('(SchemaType/Fields/FieldSchema/ValidContent/ValidValueContent/ns1:KeyValueOfstringstring/ns1:Value)[1]', 'varchar(10)')
FROM
#XmlTable
I defined the top-level XML namespace as the "default" namespace (that doesn't need to be referenced all over the place), and the second namespace deep inside your structure is defined explicitly with a separate XML namespace prefix.
I am unsure how to get the value of dc:creator from an RSS-feed using SQL.
This is my xml/rss-feed:
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<title>Foobar RSS</title>
<link>http://www.foobar.com/</link>
<description>RSS feed</description>
<language>en</language>
<ttl>15</ttl>
<item>
<title>This is my title</title>
<link>http://www.foobar.com/link/blabla</link>
<description>Bla..bla..bla..</description>
<dc:creator>John Doe</dc:creator>
<guid isPermaLink="false">00082EA751F1D905DE00E7CFA2417DA9</guid>
<pubDate>Wed, 26 Oct 2011 00:00:00 +0200</pubDate>
</item>
</channel>
</rss>
In my SQL I use something like this to get the values - e.g for pubDate I use something like this:
DECLARE #xml XML
SET #xml = cast('my rss feed here' AS xml)
SELECT
convert(datetime,substring(T.nref.value('pubDate[1]','nvarchar(100)'),6,20)) as pubdate,
FROM #xml.nodes('//item') AS T(nref)
This works fine, but when I am trying to get dc:creator value 'John Doe', the following just gives me an error:
SELECT
T.nref.value('dc:creator','nvarchar(100)') as creator
FROM #xml.nodes('//item') AS T(nref)
error:
XQuery [value()]: The name "dc" does not denote a namespace.
I need to be able to select multiple columns from the rss-feed. Can anybody provide a solution or direction to get the value of dc:creator?
I have another question - how would you construct the code if you are doing it in a sub select?
E.g.
INSERT INTO RSSResults (ID, pubDate)
SELECT #ID, tbl.pubDate FROM (
;WITH XMLNAMESPACES('http://purl.org/dc/elements/1.1/' AS dc)
SELECT
RSS.Item.value('(dc:creator)[1]', 'nvarchar(100)') as pubDate
FROM
#xml.nodes('/rss/channel/item') as RSS(Item)) AS tbl
The code breaks at ";WITH XMLNAMESPACES". Is it possible to include the namespace directly in the statement somehow?
Try something like this:
DECLARE #xml XML
SET #xml = cast('my rss feed here' AS xml)
;WITH XMLNAMESPACES('http://purl.org/dc/elements/1.1/' AS dc)
SELECT
#xml.value('(rss/channel/item/dc:creator)[1]', 'nvarchar(100)')
If you need to catch multiple items - try this:
DECLARE #xml XML
SET #xml = cast('my rss feed here' AS xml)
;WITH XMLNAMESPACES('http://purl.org/dc/elements/1.1/' AS dc)
SELECT
RSS.Item.value('(dc:creator)[1]', 'nvarchar(100)')
FROM
#xml.nodes('/rss/channel/item') as RSS(Item)
If I have:
<quotes>
<quote>
<name>john</name>
<content>something or other</content>
</quote>
<quote>
<name>mary</name>
<content>random stuff</content>
</quote>
</quotes>
How do I get a list of the element names 'name' and 'content' using T-SQL?
The best I've got so far is:
declare #xml xml
set #xml = ...
select r.value('quotes/name()[1]', 'nvarchar(20)' as ElementName
from #xml.nodes('/quotes') as records(r)
But, of course, I can't get this to work.
Actually, sorry, the best I've got is:
select distinct r.value('fn:local-name(.)', 'nvarchar(50)') as t
FROM
#xml.nodes('//quotes/*/*') AS records(r)
Guess I answered my own question...
DECLARE #xml as xml
SET #xml = '<Address><Home>LINE1</Home></Address>'
SELECT Nodes.Name.query('local-name(.)') FROM #xml.nodes('//*') As Nodes(Name)
This will give the list of all elements