简体   繁体   中英

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM