Xml của bạn bao gồm không gian tên xmlns="http://www.webserviceX.NET/"
, là không gian tên mặc định . Bạn phải khai báo hoặc sử dụng ký tự đại diện cho tiền tố.
Với XML, có một số phương pháp hay nhất:
- Càng cụ thể càng tốt
- Chỉ điều hướng về phía trước
- Quan trọng Nếu việc tạo XML nằm trong tầm kiểm soát của bạn, hãy thay đổi định dạng ngày và giờ thành ISO8601. Định dạng của bạn là văn hóa cụ thể và có thể dễ dàng dẫn đến lỗi chuyển đổi trên các hệ thống khác nhau. Tốt nhất là giá trị kết hợp như
<DateAndTime>2017-05-23T12:37:00</DateAndTime>
Đối với vấn đề của bạn, có một số cách tiếp cận:
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>';
- Cách tiếp cận tốt nhất:XMLNAMESPACES
để khai báo không gian tên mặc định
WITH XMLNAMESPACES(DEFAULT 'http://www.webserviceX.NET/')
SELECT @xml.value(N'(/string/StockQuotes/Stock/Symbol/text())[1]',N'nvarchar(max)');
- Khai báo không gian tên rõ ràng:
SELECT @xml.value(N'declare namespace ns="http://www.webserviceX.NET/";
(/ns:string/ns:StockQuotes/ns:Stock/ns:Symbol/text())[1]',N'nvarchar(max)');
--Không được khuyến khích trong hầu hết các trường hợp, nhưng tốt cho những người lười biếng :-D
SELECT @xml.value(N'(//*:Symbol)[1]',N'nvarchar(max)');
--Nếu bạn muốn đọc thêm các giá trị cùng cấp, bạn có thể sử dụng .nodes
để đặt nút hiện tại thành ...<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);