2010-06-11 12 views
25

Czy istnieje sposób na zbudowanie XPath, która ocenia, czy wartość elementu znajduje się na predefiniowanej liście wartości? Coś podobnego do tego:XPath 1.0, aby sprawdzić, czy wartość elementu znajduje się na liście wartości

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

Który pasowałby do węzłów z elementami stanu dla Teksasu, Alabamy lub Massachusetts? Wiem, że mogę rozpakować wyrażenie:

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

Ale jest to nieco kłopotliwe, ponieważ xpaths są dość długa, jak lista wartości. Moje google-fu nie obraca się znacznie w kwestii ...

Odpowiedz

43

Możesz sprawdzić wiele warunków wewnątrz samych nawiasach kwadratowych:

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

Lub jeśli masz naprawdę długą listę, można utworzyć listę stanów i użyj funkcji .

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

To zadziała dobrze w przypadku dwuliterowych skrótów stanu. Jeśli chcesz, aby był bardziej odporny na dłuższe łańcuchy, możesz dodać spacje na końcach i sprawdzić pod kątem _TX_, _AL_ itd. (Gdzie podkreślenia są spacjami).

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

Po prostu nekromancji, ponieważ XPath 2.0 nadszedł.

Z XPath 2.0, można zrobić:

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

Alternatywnie, z XPath 1.0, można użyć zawiera w połączeniu ze stringami-Length:

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; 
Powiązane problemy