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...
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, ' '))]
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;