Twój plik xml zawiera przestrzeń nazw xmlns="http://www.webserviceX.NET/"
, czyli domyślna przestrzeń nazw . Musisz go zadeklarować lub użyć symbolu wieloznacznego jako prefiksu.
W przypadku XML istnieje kilka najlepszych praktyk:
- Bądź jak najbardziej konkretny
- Tylko nawigacja do przodu
- Ważne Jeśli tworzenie XML jest pod Twoją kontrolą, zmień format daty i godziny na ISO8601. Twoje formaty są specyficzne dla kultury i mogą łatwo prowadzić do błędów konwersji w różnych systemach. Najlepsza była połączona wartość, taka jak
<DateAndTime>2017-05-23T12:37:00</DateAndTime>
W przypadku Twojego problemu istnieje kilka podejść:
DECLARE @xml XML=
N'<string xmlns="http://www.webserviceX.NET/">
<StockQuotes>
<Stock>
<Symbol>ENGI.PA</Symbol>
<Last>13.53</Last>
<Date>5/23/2017</Date>
<Time>12:37pm</Time>
<!--more elements -->
</Stock>
</StockQuotes>
</string>';
--Najlepsze podejście:XMLNAMESPACES
zadeklarować domyślną przestrzeń nazw
WITH XMLNAMESPACES(DEFAULT 'http://www.webserviceX.NET/')
SELECT @xml.value(N'(/string/StockQuotes/Stock/Symbol/text())[1]',N'nvarchar(max)');
--Niejawna deklaracja przestrzeni nazw:
SELECT @xml.value(N'declare namespace ns="http://www.webserviceX.NET/";
(/ns:string/ns:StockQuotes/ns:Stock/ns:Symbol/text())[1]',N'nvarchar(max)');
--W większości przypadków niezalecane, ale dobre dla leniwych :-D
SELECT @xml.value(N'(//*:Symbol)[1]',N'nvarchar(max)');
--Jeśli chcesz przeczytać więcej wartości tego samego poziomu, możesz użyć .nodes
aby ustawić bieżący węzeł na ...<Stock>
.
WITH XMLNAMESPACES(DEFAULT 'http://www.webserviceX.NET/')
SELECT st.value('(Symbol/text())[1]',N'nvarchar(max)')
,st.value('(Last/text())[1]',N'decimal(10,4)')
--more nodes
FROM @xml.nodes(N'/string/StockQuotes/Stock') AS A(st);