2011-04-14 22 views
27

上記のxmlサンプルでは、​​xpathを使用して、クラスfooに属し、クラスバーにないすべての書籍を選択したいと考えています。先頭と末尾のスペースで@class値をパディングすることによってXpathで複数のクラスを持つ要素を選択するにはどうすればよいですか?

<?xml version="1.0" encoding="ISO-8859-1"?> 
<bookstore> 
    <book class="foo"> 
    <title lang="en">Harry Potter</title> 
    <author>J K. Rowling</author> 
    <year>2005</year> 
    <price>29.99</price> 
    </book> 
    <book class="foo bar"> 
    <title lang="en">Harry Potter</title> 
    <author>J K. Rowling</author> 
    <year>2005</year> 
    <price>29.99</price> 
    </book> 
    <book class="foo bar"> 
    <title lang="en">Harry Potter</title> 
    <author>J K. Rowling</author> 
    <year>2005</year> 
    <price>29.99</price> 
    </book> 
</bookstore> 
+2

良い質問、1。最初のものが特に最適化されていないXPath 2.0エンジンを使用した場合、最も効率的な2つの異なるXPath 2.0ソリューションについては、私の答えをご覧ください。 –

答えて

33

、あなたは「foo」と「bar」ではなく、それは最初にあったかどうかを心配し、途中、または最後の、そして任意の偽陽性の存在をテストすることができますに「食品」または「不毛」@class値のヒットは:

/bookstore/book[contains(concat(' ',@class,' '),' foo ') 
     and not(contains(concat(' ',@class,' '),' bar '))] 
+1

'@ class'に空白ではなくタブや改行文字が含まれているとどうなりますか?文字列から先頭と末尾の空白を取り除き、空白文字のシーケンスを1つの空白で置き換える 'normalize-space'関数(XPath 1.0)が便利です。 'concat( ''、normalize-space(@class)、 '')' –

+0

@Steven Pribilinskiy - これは必要ではありません。属性値がXMLパーサーによってどのように正規化されるかによって、タブとキャリッジリターンは既にスペースに正規化されています。 http://www.w3.org/TR/xml/#AVNormalize –

+0

これは良い答えです:http://stackoverflow.com/a/3881148/557406 –

11

私はマッズソリューションを好むものの:

/bookstore/book[ 
       tokenize(@class," ")="foo" 
       and not(tokenize(@class," ")="bar") 
       ] 

はそのトンに注意してください:ここではXPath 2.0のための別のアプローチがあります彼次の式は両方とも真である:

("foo","bar")="foo" -> true 
("foo","bar")="bar" -> true 
+0

+1 XPath 2.0のソリューションです。 2.0では非常に多くのことが簡単です。 –

4

のXPath 2.0:ここ

/*/*[for $s in concat(' ',@class,' ') 
      return 
       matches($s, ' foo ') 
      and 
       not(matches($s, ' bar ')) 
     ] 

何のトークン化が行われず、$ sは一度だけ計算されます。

あるいは

/*/book[@class 
      [every $t in tokenize(.,' ') satisfies $t ne 'bar'] 
      [some $t in tokenize(.,' ') satisfies $t eq 'foo'] 
     ] 
+0

+1を1回の計算最適化に使用します。 – topless

+0

@ Chris-Top:どうぞよろしくお願いいたします。 –

関連する問題