Вашият xml включва пространство от имена xmlns="http://www.webserviceX.NET/"
, което е именното пространство по подразбиране . Трябва или да го декларирате, или да използвате заместващ знак за префикса.
С XML има някои най-добри практики:
- Бъдете възможно най-конкретни
- Само навигация напред
- Важно Ако създаването на XML е под ваш контрол, променете формата за дата и час на ISO8601. Вашите формати са специфични за културата и могат лесно да доведат до грешки при преобразуване на различни системи. Най-добрата беше комбинирана стойност като
<DateAndTime>2017-05-23T12:37:00</DateAndTime>
За вашия проблем има няколко подхода:
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>';
--Най-добър подход:XMLNAMESPACES
за да декларирате пространството от имена по подразбиране
WITH XMLNAMESPACES(DEFAULT 'http://www.webserviceX.NET/')
SELECT @xml.value(N'(/string/StockQuotes/Stock/Symbol/text())[1]',N'nvarchar(max)');
--Неявна декларация на пространство от имена:
SELECT @xml.value(N'declare namespace ns="http://www.webserviceX.NET/";
(/ns:string/ns:StockQuotes/ns:Stock/ns:Symbol/text())[1]',N'nvarchar(max)');
--Не се препоръчва в повечето случаи, но е добре за мързеливи хора :-D
SELECT @xml.value(N'(//*:Symbol)[1]',N'nvarchar(max)');
--Ако искате да прочетете повече стойности от същото ниво, можете да използвате .nodes
за да зададете текущия възел на ...<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);