Extract xml value from table SQL Server - sql

I am trying to extract value from xml in table.PFB sample xml.
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfKeyValue xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<KeyValue>
<Key>[#Id#]</Key>
<Value>354005</Value>
</ArrayOfKeyValue>
I am trying below script and it is not working.
SELECT
CAST(CAST(([KeyWordValues]) AS ntext) AS XML).value('(/ArrayOfKeyValue/KeyValue[1])', 'nvarchar(max)')
FROM
Table
I'm getting this error :
Msg 2389, Level 16, State 1, Line 1
XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
Please note XML is saved as varchar in the database.
Please help. Thanks in advance

Thanks alot for help. I got it working.
SELECT cast(cast(([KeyWordValues]) as ntext) as
xml).value('(/ArrayOfKeyValue/KeyValue/Value)[1]', 'nvarchar(max)')
FROM Table

Related

Error "The name "soap" does not denote a namespace" if i try to parse XML in T-sql

When i try to parse XML in T-sql I get error "The name "soap" does not denote a namespace"
This is my XML and query. Answer, please, how can I parse such XML. Thanks.
DECLARE #xml xml
SET #xml =
'<soap:Envelope xmlns:soap=http://schemas.xmlsoap.org/soap/envelope/>
<soap:Body>
<GetWebLinkResponse xmlns=http://test.org/ xmlns:ns2=http://schemas.datacontract.org/2004/07/.Configuration xmlns:ns3=http://schemas.datacontract.org/2004/07/.Configuration.Results xmlns:ns4=http://schemas.microsoft.com/2003/10/Serialization/>
<GetWebLinkResult>
<ns3:Error>
<ns2:Id>0</ns2:Id>
<ns2:Text>Success.</ns2:Text>
</ns3:Error>
<ns3:Url>
https://example.com&content=true
</ns3:Url>
</GetWebLinkResult>
</GetWebLinkResponse>
</soap:Body>
</soap:Envelope>'
SELECT
-- n.value('(./Code/text())[1]','int') as CODE
--,
n.value('ns3:Url','varchar(1000)')as NAME
FROM #xml.nodes('/soap:Envelope/soap:Body/GetWebLinkResponse/GetWebLinkResult') as a(n)
First of all - your XML is invalid - your namespace definitions must be in double quotes:
DECLARE #xml xml
SET #xml =
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetWebLinkResponse xmlns="http://test.org/" xmlns:ns2="http://schemas.datacontract.org/2004/07/.Configuration" xmlns:ns3="http://schemas.datacontract.org/2004/07/.Configuration.Results" xmlns:ns4="http://schemas.microsoft.com/2003/10/Serialization/">
<GetWebLinkResult>
<ns3:Error>
<ns2:Id>0</ns2:Id>
<ns2:Text>Success.</ns2:Text>
</ns3:Error>
<ns3:Url>
https://example.com&content=true
</ns3:Url>
</GetWebLinkResult>
</GetWebLinkResponse>
</soap:Body>
</soap:Envelope>';
Once you've corrected that, you'll need to define all relevant XML namespaces for your T-SQL query. Relevant XML namespaces are all explicitly used namespaces (like soap: and ns3:), as well as default namespaces like the xmlns="http://test.org/" on your <GetWebLinkResponse> node.
When you declare them all - the T-SQL query should work:
WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS soap,
'http://schemas.datacontract.org/2004/07/.Configuration.Results' as ns3,
DEFAULT 'http://test.org/')
SELECT
n.value('(ns3:Url)[1]', 'varchar(1000)') AS NAME
FROM
#xml.nodes('/soap:Envelope/soap:Body/GetWebLinkResponse/GetWebLinkResult') as a(n)

How to get value of a node with namespace prefix [duplicate]

This question already has answers here:
sql server parse xml with namespace
(2 answers)
Closed 11 months ago.
So, I have got the following query that I tried to get the value between the nodes:
<oas:Base64Assertion>235fkl53</oas:Base64Assertion>
I want to extract the value 235fkl53. I tried with the following query:
declare #x xml = '
<soapenv:Header>
<oas:Security>
<oas:Base64Assertion>
<oas:Security xmlns:oas="http://example.com">
<oas:Base64Assertion>235fkl53</oas:Base64Assertion>
</oas:Security>
</oas:Base64Assertion>
</oas:Security>
</soapenv:Header>
';
select cast(#x.value('(//oas:Base64Assertion)[1]', 'nvarchar(max)') as xml).query('//value/text()') as cdata;
But I get the following error:
Msg 2229, Level 16, State 1, Line 13 XQuery [value()]: The name "oas"
does not denote a namespace.
Any tips on how to achieve this?
You did not add the namespaces in the XML you posted so I have added them in the following example based on where I think they should be.
You need to add WITH NAMESPACE before using namespace prefixes in XQueries:
declare #x xml = '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:oas="http://example.com">
<soapenv:Header>
<oas:Security>
<oas:Base64Assertion>
<oas:Security>
<oas:Base64Assertion>235fkl53</oas:Base64Assertion>
</oas:Security>
</oas:Base64Assertion>
</oas:Security>
</soapenv:Header>
</soapenv:Envelope>
';
WITH XMLNAMESPACES ('http://example.com' AS oas)
SELECT #x.value('(//oas:Base64Assertion)[1]', 'nvarchar(max)');
SELECT #x.value('declare namespace oas="http://example.com"; (//oas:Base64Assertion)[1]', 'nvarchar(max)');
DB<>Fiddle

SQL Query to Pars Out a Value from NTEXT (XML format) field

I have XML data in an NTEXT field (ou.ORDMODE), that I need to parse out a value (description) from. Column may contain null values. The data looks like this:
<?xml version="1.0" encoding="utf-16"?>
<UDFValidatedValue xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Accellos.Platform.UDF">
<Description>Export</Description>
<Value>EXP</Value>
<ValueType>String</ValueType>
</UDFValidatedValue>
The line I have in my query is this:
CAST(REPLACE(CAST(ou.ORDMODE as NVARCHAR(MAX)),' xmlns="http://schemas.datacontract.org/2004/07/Accellos.Platform.UDF"','') as XML).value ('(/UDFValidatedValue/Description/text())[0]', 'nvarchar(100)') as Mode3,
but Mode3 column is returned as blank.
What am I doing wrong?
You could use this:
DEclare #xml xml = N'<?xml version="1.0" encoding="utf-16"?>
<UDFValidatedValue xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Accellos.Platform.UDF">
<Description>Export</Description>
<Value>EXP</Value>
<ValueType>String</ValueType>
</UDFValidatedValue>';
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Accellos.Platform.UDF')
select #xml.value ('(/UDFValidatedValue/Description)[1]', 'nvarchar(100)') as Mode3
or
select #xml.value ('declare namespace
udf="http://schemas.datacontract.org/2004/07/Accellos.Platform.UDF";
(/udf:UDFValidatedValue/udf:Description)[1]', 'nvarchar(100)') as Mode3
Demo link: Rextester
As ZLK pointed out in his comment, your own approach seems to be quite okay, just the index must be 1 instead of 0. Try it here:
ad "quite okay": Actually this is absolutely far away from "quite okay", read my hint below...
DECLARE #tbl TABLE(SomeXmlInText TEXT);
INSERT INTO #tbl VALUES
('<?xml version="1.0" encoding="utf-16"?>
<UDFValidatedValue xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Accellos.Platform.UDF">
<Description>Export</Description>
<Value>EXP</Value>
<ValueType>String</ValueType>
</UDFValidatedValue>');
SELECT SomeXmlInText
,CAST(REPLACE(CAST(SomeXmlInText as NVARCHAR(MAX)),' xmlns="http://schemas.datacontract.org/2004/07/Accellos.Platform.UDF"','') as XML).value ('(/UDFValidatedValue/Description/text())[1]', 'nvarchar(100)') as Mode3
FROM #tbl
From your answer I take, that there is still no result...
Some possible issues:
XML is not really as you expect it
more / other namespaces
some weird no, not for you issue :-D
Hint
As you probably know TEXT, NTEXT and IMAGE are deprecated for centuries and should really not be used any more... If you have the slightest chance to change this, then you should store your XML in the appropritate XML-type...
You should not need any casts or manipulations on string level. This can be working, but is really out-dated...

Extracting values from XML field with unusual XML using SQL

Hoping someone can help -
The XML format was put together with a very simple syntax, but for some reason I'm struggling to parse it using a standard 'value' type query.
I'm experienced with SQL, but only have limited experience in XML, and after 2 hours of frustration and much Googling, I thought I'd ask for my own sanity!
The data is stored as a text string, so converting it to XML before parsing:
<!-- Data config file -->
<Config>
<!-- keys-->
<foo value="bar"/>
<foo1 value="bar1"/>
<big_foo value="bar/bar.com"/>
<other value="f00"/>
The query I'm using is:
SELECT
col.value('foo1[0]', 'nvarchar(max)') as VALUE
from
(
select
CAST((SELECT TOP 1 xml_text FROM dbo.xml_lookup)AS XML)
as Col)x
but this returns NULL rather than the expected "bar1".
Any idea where I'm going wrong?
proper XPath would be
col.value('(Config/foo1)[1]/#value', 'nvarchar(max)')
sql fiddle demo

Xml query resulting in error in sql server

This is my xml query
declare #XML xml
set #XML=
'<ROOT>
<Customers>
<CustomerId>1111</CustomerId>
<CompanyName>Sean Chai</CompanyName>
<City>NY</City>
</Customers>
<Customers>
<CustomerId>1112</CustomerId>
<CompanyName>Tom Johnston</CompanyName>
<City>LA</City>
</Customers>
<Customers>
<CustomerId>1113</CustomerId>
<CompanyName>Institute of Art</CompanyName>
</Customers>
</ROOT>';
SELECT
R.Node('.').value('(/Customers/CustomerId/.)[1]','varchar(100)') AS CustomerID,
R.Node('.').value('(/Customers/CompanyName/.)[1]','varchar(100)') AS CompanyName
FROM #XML.nodes('/ROOT/Customers') R(Node)
But its giving error:
Msg 4121, Level 16, State 1, Line 20
Cannot find either column "R" or the user-defined function or aggregate "R.Node", or the name is ambiguous.
i searched but couldn't get R.node Thing pls somebody guide me onthis !
and i'm not understanding #XML.nodes('/ROOT/Customers') R(Node) ?
what is its use in query!
Change the query like this and try
SELECT
R.Node.value('(CustomerId/.)[1]','varchar(100)') AS CustomerID,
R.Node.value('(CompanyName/.)[1]','varchar(100)') AS CompanyName
FROM #XML.nodes('/ROOT/Customers') R(Node)
First of all you have syntax error in your query. You have aliase to your resultant table as R(Node), then you cannot specifiy the path as R.Node(.).
Secondly the path that you mentioned in your query is wrong (/Customers/CustomerId/.)