2010-06-11 38 views
25

Có cách nào để xây dựng XPath đánh giá liệu giá trị của một phần tử có nằm trong danh sách giá trị được xác định trước hay không? Một cái gì đó giống như thế này:XPath 1.0 để tìm xem liệu giá trị của một phần tử có nằm trong danh sách giá trị

/Location/Addr[State='TX or AL or MA'] 

Nút nào khớp với các nút whith Các phần tử trạng thái cho Texas, Alabama hoặc Massachusetts? Tôi biết rằng tôi có thể giải nén biểu thức:

/Location/Addr[State='TX] or /Location/Addr[State='AL'], etc... 

Nhưng điều này hơi cồng kềnh vì các xpath khá dài, cũng như danh sách giá trị. Google-fu không chuyển lên nhiều về vấn đề này ...

Trả lời

43

Bạn có thể kiểm tra nhiều điều kiện bên trong dấu ngoặc vuông giống nhau:

/Location/Addr[State='TX' or State='AL' or State='MA'] 

Hoặc nếu bạn có một danh sách rất dài, bạn có thể tạo danh sách các trạng thái và sử dụng hàm .

/Location/Addr[contains('TX AL MA', State)] 

Điều này sẽ hoạt động tốt cho chữ viết tắt hai chữ cái của tiểu bang. Nếu bạn muốn làm cho nó mạnh mẽ hơn cho các chuỗi dài hơn, bạn có thể thêm một số khoảng trống ở đầu và kiểm tra _TX_, _AL_, v.v. (trong đó dấu gạch dưới là dấu cách).

/Location/Addr[contains(' TX AL MA ', concat(' ', State, ' '))] 
3

Chỉ cần necromancing, vì XPath 2.0 đã xuất hiện.

Với XPath 2.0, bạn có thể làm:

/Location/Addr[State=('TX', 'AL', 'MA')] 

Ngoài ra, với XPath 1.0, bạn có thể sử dụng chứa kết hợp với chuỗi dài:

declare @tXML xml = '<svg> 
<g> 
<path></path> 
<path data-objid="0000X1"></path> 
<path data-objid="0000X2"></path> 
<path data-objid="0000X3"></path> 
</g> 
</svg>'; 

-- select @tXML; 

SELECT 
    c.p.value('(@data-objid)[1]', 'varchar(50)') AS 'DocumentID' 
FROM @tXML.nodes('//node()[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]') AS c(p) 


set @tXML.modify('delete //node()[contains("0000X1,0000X2", @data-objid) and string-length(@data-objid) != 0]'); 

select @tXML; 
Các vấn đề liên quan