2010-06-11 25 views
25

有沒有一種方法可以構造一個XPath來評估一個元素的值是否在預定義的值列表中?類似於這樣的東西:XPath 1.0找到一個元素的值是否在值列表中

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

哪個匹配德克薩斯州,阿拉巴馬州或馬薩諸塞州的州級元素節點?我知道我可以解開這個表達式:

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

但是這樣做有點麻煩,因爲xpaths非常長,正如值列表一樣。我的谷歌福沒有在這個問題上轉動起來了...

回答

43

您可以查看同方括號內的多個條件:

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

或者,如果你有一個很長的列表,您可以創建狀態列表並使用函數。

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

這對兩個字母的狀態縮寫可以正常工作。如果你想讓它對於更長的字符串更健壯,你可以在兩端添加一些空格並檢查_TX_,_AL_等(其中下劃線是空格)。

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

自從XPath 2.0問世以來,只是不了了之。

在XPath 2.0,可以做到:

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

可替代地,使用XPath 1.0,則可以使用含有結合串長度:

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; 
相關問題