XPath 1.0 Pour trouver si la valeur d'un élément est dans une liste de valeurs

Existe-t-il un moyen de construire un XPath qui évalue si la valeur d'un élément est dans une liste prédéfinie de valeurs? Quelque chose qui s'apparente à ceci:

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

Qui correspondrait à des nœuds avec des éléments D'État pour le Texas, L'Alabama ou le Massachusetts? Je sais que je peux déballer l'expression:

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

Mais c'est un peu lourd car les xpaths sont assez longs, tout comme la liste des valeurs. Mon google-fu ne tourne pas beaucoup sur la question...

26
demandé sur John Kugelman 2010-06-12 00:08:02

2 réponses

Vous pouvez vérifier plusieurs conditions dans les mêmes crochets:

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

Ou si vous avez une liste très longue, vous pouvez créer une liste d'États et utiliser la fonction contains().

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

Cela fonctionnera bien pour les abréviations d'État à deux lettres. Si vous voulez le rendre plus robuste pour les chaînes plus longues, vous pouvez ajouter certains espaces sur les extrémités et vérifier _TX_, _AL_, etc. (où les traits de soulignement sont des espaces).

/Location/Addr[contains(' TX AL MA ', concat(' ', State, ' '))]
47
répondu John Kugelman 2010-06-11 20:21:04

Juste nécromancie, puisque XPath 2.0 est arrivé.

Avec XPath 2.0, vous pouvez faire:

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

Alternativement, avec XPath 1.0, vous pouvez utiliser contains en combinaison avec string-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;
6
répondu Stefan Steiger 2017-07-07 10:56:15