2009-10-13 11 views
30

Mam coś jak poniżej XML w kolumnie tabeli:Jak zdobyć konkretny atrybut z elementu XML w SQL Server

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

próbuję dostać część valueB z XML za pomocą TSQL

Do tej pory otrzymuję właściwy węzeł, ale teraz nie mogę wymyślić, jak uzyskać atrybut.

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

Myślę, że mógłbym tylko dodać/@ wartość do końca, ale potem SQL powiedział mi, że atrybuty muszą być częścią węzła. Mogę znaleźć wiele przykładów wyboru atrybutów węzłów potomnych, ale nic na atrybuty rodzeństwa (jeśli jest to odpowiedni termin).

Każda pomoc zostanie doceniona.

Odpowiedz

51

Spróbuj użyć funkcji .value zamiast .query:

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

Wyrażenie XPath może potencjalnie zwrócić listę węzłów, więc trzeba dodać [1] tej potencjalnej listy powiedzieć SQL Server do używania jako pierwszy tych wpisów (i tak - ta lista jest oparta na 1 - nie na 0). Jako drugi parametr musisz określić, w jakim typie wartość ma być konwertowana - po prostu zgaduj tutaj.

Marc

+1

Dzięki. Dokładnie to, czego potrzebowałem. –

+0

mam dynamiczne węzły w polu jak Używając zapytanie dać Umiem czytać według indeksu. Znaczy Kiedy podam indeks jako 1, wyświetli on 2, a kiedy podam indeks 2, wyświetli 5, ale ja wymaga obu węzłów. więc proszę, zasugeruj mi, jak to zrobić! – pixelbyaj

+0

Mam problem z użyciem tego dla wartości logicznej. Próbowałem używać "boolean" i "System.Boolean" jako drugie parametry i otrzymałem błąd. Jeśli zrobię varchar, zwróci on wszystkie wartości null. Moja linia xml wygląda następująco: Zac

5

zależności od rzeczywistej struktury swojej xml, może to być przydatne, aby umieścić widok na to, aby łatwiej spożywać za pomocą „zwykłej” sql np

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

Dlaczego xmlCol.value ("(/ container/param [@ name =" paramB "]/@ value) [1] ',' varchar (50) ') nie działa dla mnie, ale tylko .value (' @ value ' , "vharchar (50)") działa? Hmmmmm. – AndyClaw

0

$doc/param[@value = "valueB"]/fn:data(@value)
Zakładając, że $ doc ma Xml.