I have an XML like:
<?xml version="1.0" encoding="utf-16"?>
<ExportProjectDetailsMessage xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Project">
<CPProjectId>7665699f-6772-424c-8b7b-405b9220a8e7</CPProjectId>
</ExportProjectDetailsMessage>
I'm trying to get the CPProjectId as a Uniqueidentifier using:
DECLARE @myDoc xml
DECLARE @ProdID varchar(max)
SET @myDoc = '<ExportProjectDetailsMessage xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Project"><CPProjectId>7665699f-6772-424c-8b7b-405b9220a8e7</CPProjectId></ExportProjectDetailsMessage>'
SET @ProdID = @myDoc.value('(ExportProjectDetailsMessage/CPProjectId)[1]', 'varchar(max)' )
SELECT @ProdID
All i can receive is NULL =/ I've tried many combinations on @myDoc.value but no results =/
How can i retrieve the value from my XML ?
Thanks!
--EDIT: Something that i noted, when i remove the namespace declaration from the XML it works fine! The problem is that i need this namespaces! =/
You can retrieve multiple values from the rowset. For example, you can apply the value() method to the rowset returned by nodes() and retrieve multiple values from the original XML instance. The value() method, when applied to the XML instance, returns only one value.
You can optionally retrieve formal results of a SQL query as XML by specifying the FOR XML clause in the query. The FOR XML clause can be used in top-level queries and in subqueries. The top-level FOR XML clause can be used only in the SELECT statement.
You should use the query() Method if you want to get a part of your XML. If you want the value from a specific node you should use value() Method. Update: If you want to shred your XML to multiple rows you use nodes() Method.
XML data can be queried using an SQL fullselect or with the SQL/XML query functions of XMLQUERY and XMLTABLE. The XMLEXISTS predicate can also be used in SQL queries on XML data.
You're right the namespace is the issue. You're query is looking for a node ExportProjectDetailsMessage but such a node doesn't exist in your document, because there is a namespace declared as a default in your document. Since you can't remove that (nor should you) you should include it in your XPATH query like so:
set @ProdId = @myDoc.value('
declare namespace PD="http://schemas.datacontract.org/2004/07/Project";
(PD:ExportProjectDetailsMessage/PD:CPProjectId)[1]', 'varchar(max)' )
You may also want to consider not using varchar(max) but perhaps uniqueidentifier
A better way to do this is to simply declare the namespace before each of your queries:
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Project')
It's like a temporary default. When you run the next query in the batch you'll get nulls again if you don't specify this before each of your selects.
So instead of using "SET", you can use "SELECT" to set the value like so:
;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Project')
SELECT @ProdID = @myDoc.value('(ExportProjectDetailsMessage/CPProjectId)[1]', 'VarChar(MAX)')
SELECT @ProdID
Same results, just more readable and maintainable. I found the solution here: http://www.sqlservercentral.com/Forums/Topic967100-145-1.aspx#bm967325
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With