2

次のようなXMLがあります。

<container>
  <type>01</type>
  <text>one</text>
</container>
<container>
  <type>02</type>
  <text>two</text>
</container>

編集sの順序はcontainer固定されていません。

このドキュメントからテキストを選択するために(rubyのnokogiriを介して)xPathを使用しています。02のでを取り込めるようにしたいのですが、textそれcontainerが存在しない場合は01のでから取ります。typetextcontainertype

できます

/container/type[text() = "02" or text() = "01"]/parent::container

これで両方の要素が得られます。次に、ルビーを使用して正しい要素を並べ替えて取得できます(これにより、最初に01要素が返されます)が、これは不器用です。

私はstackoverflowを検索しましたが、単純なxpathで要素出力を並べ替えることができるものはすぐにはわかりませんが、要素を取得するようにxpathに命令する方法はありますが、存在しない場合は別の要素にフォールバックしますか?

乾杯!

4

3 に答える 3

2

あなたがそれを好きになるかどうかはわかりませんが、それはあなたが望むことをします:

concat(substring(//container[type/text() = '02']/text,1,string-length(//container[type/text()='02'])*boolean(//container[type/text()='02']/text())),substring(//container[type/text() = '01']/text,1,string-length(//container[type/text()='01'])*number(boolean(//container[type/text()='01']/text())and not(boolean(//container[type/text()='02']/text())))))

すぐに分解します...


OK、この部分:

concat(

substring(//container[type/text() = '02']/text,1,string-length(//container[type/text()='02'])*boolean(//container[type/text()='02']/text())),

<text>from type = 2が存在する場合は、それを取得します。

この部分:

substring(//container[type/text() = '01']/text,1,string-length(//container[type/text()='01'])

from type = 1を取得し、<text>これを使用してtype=2が存在しない場合にのみ返します。

*number(boolean(//container[type/text()='01']/text())and not(boolean(//container[type/text()='02']/text())))))

それがそれをクリアするのに役立つことを願っています、私はあなたが何かきれいなものを探していたことを知っています、しかしあなたがXPathを使って欲しかったもののために、それは少し厄介です。

于 2012-12-20T16:03:48.933 に答える
0

順序が決まっている場合は、両方を選択して、最後の1つを取ることができます。ドキュメント内で02しかない場合は02になり、前に01がある場合は02になります。

 (/container/type[text() = "02" or text() = "01"]/parent::container)[last()]

または、ノードの値はそのテキストであり、比較では一致するペアが検索されるため、以下のようになります。

 (/container[type = ("01", "02")])[last()]

(少なくともXPath 2で機能しますが、XPath 1でも同じかどうかはわかりません)

-

編集:

実際、それはかなり簡単です。タイプ02のコンテナがあるかどうかを確認できる//container[type = "02"]ので、タイプ02コンテナがない場合は、すべての02コンテナとすべての01コンテナを取得でき、次のようになります。

 //container[type = "02" or (type = "01" and not(//container[type = "02"]))]

かなり遅いです

于 2012-12-20T12:49:59.187 に答える
0
(//container/type[.='02'], //container/type[.='01'])[1]/..

外側の括弧は、テキスト値を持つタイプ要素と02、それに続くテキスト値を持つタイプからシーケンスを構成します01。演算子は未定義の値を省略します。,したがって、一方が欠落している場合、シーケンスは他方のみで構成され、両方が欠落している場合、それは空のシーケンスです。

[1]そのシーケンスから最初のアイテムを選択します

/..はの省略構文であり、この場合parent::node()はあなたと同等です。parent::container

あなたはこれがうまくいくと期待するかもしれません:

//container/(type[.='02'],type[.='01'])[1]/..

しかし(少なくともサクソンでは)これはあなたに両方のコンテナを与えます; またはこれ:

(//container/(type[.='02'],type[.='01']))[1]/..

ただし01、角かっこの結果は両方ともドキュメント順のノードであるため、これによりコンテナが作成されます。

于 2018-07-19T10:37:50.083 に答える