2010-06-11 8 views
25

Esiste un modo per costruire un XPath che valuti se il valore di un elemento si trova in un elenco predefinito di valori? Qualcosa di simile a questo:XPath 1.0 per trovare se il valore di un elemento si trova in un elenco di valori

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

Quale sarebbe partita nodi whith elementi di Stato per il Texas, Alabama, o Massachusetts? So che posso decomprimere l'espressione:

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

ma questo è un po 'ingombrante in quanto i XPaths sono piuttosto lunghi, come l'elenco dei valori. Il mio google-fu non gira su molto sulla questione ...

risposta

43

È possibile controllare più condizioni all'interno delle stesse parentesi quadre:

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

Oppure, se si dispone di una lunga lista, è possibile creare un elenco di stati e utilizzare la funzione .

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

Questo funzionerà bene per le abbreviazioni di stato di due lettere. Se vuoi renderlo più robusto per stringhe più lunghe, puoi aggiungere degli spazi alle estremità e controllare _TX_, _AL_, ecc. (Dove i caratteri di sottolineatura sono spazi).

3

Solo necromancing, dal momento che XPath 2.0 è arrivato.

Con XPath 2.0, si può fare:

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

In alternativa, con XPath 1.0, è possibile utilizzare contiene in combinazione con stringa di lunghezza:

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; 
Problemi correlati