Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

T-SQL XML get a value from a node problem?

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! =/

like image 857
renanleandrof Avatar asked Aug 05 '11 20:08

renanleandrof


People also ask

How do I query values in XML nodes?

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.

How can I get SQL query results in XML?

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.

How do I select a specific XML node in SQL Server?

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.

How do I query XML data?

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.


2 Answers

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

like image 108
Ralph Shillington Avatar answered Oct 28 '22 03:10

Ralph Shillington


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

like image 31
MikeTeeVee Avatar answered Oct 28 '22 04:10

MikeTeeVee