3

私は xpath でできることを探しています:これは私と//foo[@n="$1"]//bar[@n="$2"] を返すことができます. または、少なくとも両方を返してください$1$2<foo><bar>

詳細は次のとおりです。xmlドキュメントがあります。

<xml>
  <foo>
    <a n="1">
      <b n="1"/>
      <b n="2"/>
    </a>
  </foo>
  <a n="2">
    <b n="1"/>
  </a>
  <a n="3">
    <b n="1"/>
    <foo>
      <b n="2"/>
    </foo>
    <b n="3"/>
  </a>
</xml>

<a>の n 属性に基づいて文字列を生成したいので、<b> xpath: があり//a[@n]//b[@n] 、返されるすべての結果に対して、次を使用します:./@nそして、必要な./ancestor::a/@n情報を取得します。

これは正常に機能していますが、このような構造がたくさんあり、xpath を自動生成する必要があるため、もっとインテリジェントなものが必要です。

上記の例では、次のような xpath を探してい//a[@n="$1"]//b[@n="$2"] ます。 、 3)

4

1 に答える 1

4

n必要なすべての属性を選択する 1 つの XPath 1.0 式を次に示します。

//a[.//b]/@n | //a//b/@n

最適化を行わない場合、上記の式の評価は、XML ドキュメントの少なくとも 2 つの完全な走査として実行されます。

この XPath 1.0 式はより効率的である可能性があります

//*[self::a and .//b or self::b and ancestor::a]/@n

aeveryにb子孫があることが保証されている場合、両方の式を簡略化できます

それらはそれぞれ次のようになります。

//a/@n | //a//b/@n

と:

//*[self::a or self::b and ancestor::a]/@n

aeveryに子孫がbあり、すべてbに祖先があることが保証されている場合は、さらに単純化できaます。:

//*[self::a or self::b]/@n

1 つの XPath 1.0 式で、必要なすべての属性の文字列値を取得することは不可能です。上記の式のいずれかを使用してすべての属性を取得する必要があります。次に、選択した各属性に 2 番目の XPath 式を適用しますstring()

Xpath 2.0 では、必要な属性のすべての文字列値を 1 つの式で取得できます。各式に次のように追加するだけです。/string(.)

たとえば、最も単純なものは次のとおりです。

//(a|b)/@n/string(.)

更新

OPは彼の質問を明確にしました。これで、彼がこの結果を生成することを望んでいることがわかりました。

(1, 1), (1, 2), (2, 1), (3, 1), (3, 2), (3, 3)

単一の XPath 1.0 式で必要な結果を生成することはできません。

次の XPath 2.0 式は、必要な結果を生成します

for $a in //a[@n and .//b[@n]],
    $b in $a//b[@n]
  return
     concat('(', $a/@n, ',', $b/@n, ') ')
于 2012-07-07T15:39:39.347 に答える