2012-09-02 13 views
6

私は、「検索」ノードから情報を読み取り、それを使用して検索を実行できるXpathステートメント(1.0)を作成しようとしています。XPath関数 'contains()'を使用して、検索パラメータが空白の場合、または何もない場合は何も返しません。

私はいくつかの素晴らしい進歩を遂げていましたが、(検索の値に使用される)属性が空であるか存在しない場合、失敗してしまうという問題を見つけました。例簡素化する

コード編集:だからここで

は私のサンプルXMLです:

<xml> 
    <files> 
     <file name="foo" description="" rating="4"/> 
     <file name="food" description="" rating="4"/> 
     <file name="foobar" description="" rating="3"/> 
     <file name="bar" description="" rating="3"/> 
     <file name="barter" description="" rating="3"/> 
     <file name="barterer" description="" rating="2"/> 
    </files> 
    <searches> 
     <search id="1"> 
      <exclude> 
       <file term="foo"/> 
      </exclude> 
     </search> 
    </searches> 
</xml> 

と作業XPATH:

//files/file[ 
      not(contains(@name, //search[@id='1']/exclude/file/@term)) 
] 

期待どおりに動作します...

しかし、期待される属性i行方不明または空であれば動作しません。なぜなら:contains(@attrib、 "")は何らかの理由ですべてを照合するため、属性が ""であるか存在しない場合、not()は常に何も一致しません。

私はそれが失敗したこれにXMLのフラグメントを除外する変更した場合たとえば、:あまりにもこれに

  <exclude> 
       <file term=""/> 
      </exclude> 

  <exclude></exclude> 

を空の値をチェックしないようにする方法はあります選択を実行する?またはおそらくロジックを構成するためのより良い方法です。私はXpath2.0ではConditionalやその他の関数を使うことはできません。

+0

あなたは、質問を編集して、検索の一致を見つけるためのルールを記述してくださいでした:私からアイデアを得たのはここ

です - 私は短い表現が使用できると思う。たとえば、 'cond1とcond2またはcond1またはcond2'は、より短い同等の式' cond1 or cond2'で簡単に置き換えることができます。 –

+0

申し訳ありません。コード例を更新して、私の問題をより明確に指摘しました。 – Futile32

+0

@ Futile32、たぶんあなたのXPathは名前= ""のノードを取得します。空でないので、何も取得しません。 –

答えて

0

ような何かを言いたいので、私はAで答えを偶然見つけ別の投稿。以下はその動作例です。 皆様のアドバイスありがとうございます。

//files/file[ 
    not(
     contains(
      @name, 
      concat(//search[@id='1']/exclude/file/@term, 
       substring('??', 1 + 2* 
        boolean(substring(//search[@id='1']/exclude/file/@term, 1)) 
       ) 
      ) 
     ) 
    ) 
] 

「??」を配置したビットは、おそらく無効な文字などで置き換えたいと思っています。使用される追加の文字ごとに、1+の増加が必要です。私にとっては、ファイル名をチェックしているので、疑問符は良いアイデアのようです。正直言って、私はおそらくこのルートを使用しないでしょう、私はこの時間の後に問題を解決することを熱望していました。 - これらは、提供され、長いXPath式がかなり混乱していません How to give back constant if node does not exist in XPATH?

2

なぜ、XPath関数はcontainsを返しますか? paramが空白または欠落していますか?

それはXPath仕様はcontains()機能が何をすべきと言うことですので:$ ARG2の値が長さゼロの文字列、 trueを返し、その後の関数である

場合。

あなたのXPathを調整し、以下を条件の一部を簡略化することができます:

//files/file[ 
      ( 
       (
        not(//search[@id='1']/include/file/@term) 
        or 
        (
        contains(@name, //search[@id='1']/include/file/@term) 
        or 
        contains(@description, //search[@id='1']/include/file/@term) 
        ) 
       ) 
       or 
       contains(@rating, //search[@id='1']/include/file/@rating) 
      )  
      and 
      ( 
       (
        not(//search[@id='1']/exclude/file/@term) 
        or 
        (
        not(contains(@name, //search[@id='1']/exclude/file/@term)) 
        and 
        not(contains(@description, //search[@id='1']/exclude/file/@term)) 
        ) 
       ) 
       and 
       (
        not(//search[@id='1']/exclude/file/@rating) 
        or 
        not(contains(@rating, //search[@id='1']/exclude/file/@rating)) 
       ) 
      ) 

      ] 
+0

参考にしていただきありがとうございます。しかし私は、私の問題を解決するために関数を別々に使用できる方法を見つけることを望んでいたと思います。私はそれを示すために私の質問に言い直しました。 – Futile32

0

はおそらく、あなたは

//files/file[ 
    not(contains(@name, 
       //search[@id='1'] 
       /exclude/file/@term)) 
    or not(
    normalize-string(//search[@id='1'] 
         /exclude/file/@term) 
    ) 
] 
関連する問題