web-dev-qa-db-ja.com

要素の値が値のリストにあるかどうかを調べるXPath 1.0

要素の値が事前定義された値のリストにあるかどうかを評価するXPathを構築する方法はありますか?これに似たもの:

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

テキサス、アラバマ、またはマサチューセッツの州の要素を持つノードに一致するのはどれですか。式を解凍できることを知っています。

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

しかし、値のリストと同様に、xpathは非常に長いため、これは少し面倒です。私のgoogle-fuはこの問題についてあまり取り上げていません...

31
user364902

同じ角括弧内の複数の条件を確認できます。

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

または、本当に長いリストがある場合は、状態のリストを作成してcontains()関数を使用できます。

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

これは、2文字の州の略語では問題なく機能します。長い文字列に対してより堅牢にしたい場合は、末尾にスペースを追加して、__TX__、__AL__など(アンダースコアがスペース)を確認します。

_/Location/Addr[contains(' TX AL MA ', concat(' ', State, ' '))]
_
50
John Kugelman

XPath 2.0が登場して以来、ただネクロマンシングしているだけです。

XPath 2.0では、次のことが可能です。

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

または、XPath 1.0では、containsを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
Stefan Steiger