2009-10-13 66 views
30

tengo algo como lo siguiente XML en una columna de una tabla:Cómo obtener un atributo particular del elemento XML en SQL Server

<?xml version="1.0" encoding="utf-8"?> 
<container> 
    <param name="paramA" value="valueA" /> 
    <param name="paramB" value="valueB" /> 
    ... 
</container> 

que estoy tratando de llegar a la parte valorB fuera del XML a través de TSQL

Hasta ahora estoy obteniendo el nodo correcto, pero ahora no puedo entender cómo obtener el atributo.

select xmlCol.query('/container/param[@name="paramB"]') from LogTable 

Calculo que sólo pudiera añadir/@ valor hasta el final, pero luego le dice a SQL me atributos tienen que ser parte de un nodo. Puedo encontrar muchos ejemplos para seleccionar los atributos de los nodos secundarios, pero no los atributos de los hermanos (si ese es el término correcto).

Cualquier ayuda sería apreciada.

Respuesta

51

Intente utilizar la función .value en lugar de .query:

SELECT 
    xmlCol.value('(/container/param[@name="paramB"]/@value)[1]', 'varchar(50)') 
FROM 
    LogTable 

La expresión XPath potencialmente podría devolver una lista de nodos, por lo tanto, es necesario agregar un [1] a esa lista potencial para indicar a SQL Server para utilizar la primera de esas entradas (y sí, esa lista está basada en 1, no en 0). Como segundo parámetro, debe especificar a qué tipo debe convertirse el valor, simplemente adivine aquí.

Marc

+1

Gracias. Exactamente lo que necesitaba. –

+0

tengo nodos dinámicos en el campo como Mediante el uso de la consulta dar Soy capaz de leer según el índice. Significa Cuando daré el índice como un 1, se mostrará 2 y cuando le dé el índice 2, se mostrará 5 pero requiero ambos nodos. Entonces, ¿podrías sugerirme cómo hacerlo? – pixelbyaj

+0

Tengo problemas para usar esto para un booleano. Intenté usar 'boolean' y 'System.Boolean' como segundo params y recibí un error. Si hago varchar, devuelve todos los nulos. Mi línea xml se ve así: Zac

5

Dependiendo de la estructura real de su XML, puede ser útil para poner una vista sobre ella para que sea más fácil de consumir el uso de SQL 'regular' por ejemplo

CREATE VIEW vwLogTable 
AS 
SELECT 
    c.p.value('@name', 'varchar(10)') name, 
    c.p.value('@value', 'varchar(10)') value 
FROM 
    LogTable 
    CROSS APPLY x.nodes('/container/param') c(p) 
GO 


-- now you can get all values for paramB as... 
SELECT value FROM vwLogTable WHERE name = 'paramB' 
+0

¿Por qué xmlCol.value ('(/ container/param [@ name = "paramB"]/@ value) [1]', 'varchar (50)') no funciona para mí, sino simplemente .value ('@ value' , 'vcharchar (50)') funciona? Hmmmmm. – AndyClaw

0

$doc/param[@value = "valueB"]/fn:data(@value)
Suponiendo $ doc tiene el Xml.

Cuestiones relacionadas