2011-08-05 6 views
6

tengo un XML como:T-SQL XML obtiene un valor de un problema de nodo?

<?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> 

estoy tratando de conseguir el CPProjectId como Uniqueidentifier usando:

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 

Todo lo que puedo recibir es NULL =/ He probado muchas combinaciones en @ myDoc.value pero no results =/

¿Cómo puedo recuperar el valor de mi XML?

Gracias!

--EDIT: Algo que noté, cuando elimino la declaración del espacio de nombres del XML ¡funciona bien! ¡El problema es que necesito este espacio de nombres! =/

+0

Ver: http://stackoverflow.com/questions/4081906/sql-server-xml-namespace-querying-problem truco está en "espacios de nombres" y luego usando los "ns:" formar. –

Respuesta

4

Tiene razón, el espacio de nombres es el problema. Su consulta está buscando un nodo ExportProjectDetailsMessage pero dicho nodo no existe en su documento, porque hay un espacio de nombre declarado como predeterminado en su documento. Dado que no se puede quitar que (ni debe) que debe incluir en su consulta XPATH así:

set @ProdId = @myDoc.value(' 
    declare namespace PD="http://schemas.datacontract.org/2004/07/Project";   
(PD:ExportProjectDetailsMessage/PD:CPProjectId)[1]', 'varchar(max)') 

También es posible que desee considerar no usar varchar (max), pero tal vez uniqueidentifier

+0

Hombre ... Muchas gracias! ;) PD: Estaba usando varchar solo para pruebas con otros campos =] – renanlf

1

Un mejor manera de hacer esto es simplemente declarar el espacio de nombres antes de cada una de sus consultas:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Project') 

es como un defecto temporal. Cuando ejecuta la siguiente consulta en el lote obtendrá nulos nuevamente si no especifica esto antes de cada una de sus selecciones.

Así que en lugar de utilizar "SET", puede utilizar "SELECT" para establecer el valor de esta manera:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Project') 
SELECT @ProdID = @myDoc.value('(ExportProjectDetailsMessage/CPProjectId)[1]', 'VarChar(MAX)') 
SELECT @ProdID 

mismos resultados, simplemente más fácil de leer y fácil de mantener. he encontrado la solución aquí: http://www.sqlservercentral.com/Forums/Topic967100-145-1.aspx#bm967325

+1

Veo que la primera respuesta fue aceptada antes de esta respuesta. Pero por lo que vale, encontré que esta es una técnica mucho mejor (suponiendo que puede confiar en que el espacio de nombres sea consistente). – cBlaine

Cuestiones relacionadas