XPathで最も長い子#textノード値を持つXMLノードを選択するにはどうすればよいですか?

このクエリを使用する前に、XPathを使用して最大整数値のノードを選択しました。

//somenode[not(@id <= preceding::somenode/@id) and not(@id <= following::somenode/@id)]

私は私のような何かをすることができることを望んでいた:

//entry[not(string-length(child::text()) <= string-length(preceding::entry/child::text())) and not(string-length(child::text()) <= string-length(following::entry/child::text()))]

しかし、それは単なる1つではなくたくさんのノードを返します。

サンプルXML:


  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Nam dignissim mi a massa mattis rutrum eu eget mauris.
  Ut at diam a sem scelerisque pretium nec pulvinar purus.
  Nunc in nisi nec dolor accumsan suscipit vel a quam.
  Nunc suscipit lobortis arcu, nec adipiscing libero bibendum nec.
  Aenean eget ipsum et nunc eleifend scelerisque.
  In eu magna et diam volutpat molestie.
  In volutpat luctus mi, eu laoreet orci dictum vel.
  In mattis mi nec magna sodales eu bibendum felis aliquet.
<!-- etc for 800 more lines or so -->
  Duis auctor felis id neque gravida ut auctor ipsum ullamcorper.
  Sed vel tortor mauris, et aliquet tellus.

XPath test: http://chris.photobooks.com/xml/default.htm?state=1o

5

1 答え

The wanted element(s) cannot be selected with a single XPath 1.0 expression, because in XPath 1.0 it is not possible to apply a function to all selected nodes (string-length(someNodeSet) is applied only on the first node of this node-set). Another reason is that in XPath 1.0 it isn't possible to name and reference range variables.

In XPath 2.0 this is trivial:

/*/entry[not(string-length(.) < /*/entry/string-length(.))]

上の例では、すべての entry 要素を選択します。その要素の長さは最大値です。

/*/entry[not(string-length(.) < /*/entry/string-length(.))] [1]

上の例では、 entry 要素の最初の(ドキュメント順で)選択します。

XSLT 2.0 - based verification:

この変換:



 
  
 

when applied on the provided xml document:


  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  Nam dignissim mi a massa mattis rutrum eu eget mauris.
  Ut at diam a sem scelerisque pretium nec pulvinar purus.
  Nunc in nisi nec dolor accumsan suscipit vel a quam.
  Nunc suscipit lobortis arcu, nec adipiscing libero bibendum nec.
  Aenean eget ipsum et nunc eleifend scelerisque.
  In eu magna et diam volutpat molestie.
  In volutpat luctus mi, eu laoreet orci dictum vel.
  In mattis mi nec magna sodales eu bibendum felis aliquet.
<!-- etc for 800 more lines or so -->
  Duis auctor felis id neque gravida ut auctor ipsum ullamcorper.
  Sed vel tortor mauris, et aliquet tellus.

selects the entry elements (in this case only one) with the maximum string-length and outputs the selected elements:

Nunc suscipit lobortis arcu, nec adipiscing libero bibendum nec.
2
追加された
2番目のクエリで最後に [1] が見つからないと思いますか?
追加された 著者 travis,
私はちょうどこのクエリを実行する機会があり、それはすべてのノードを返すようです。したがって、2番目のノードはドキュメントの最初のノードを返します。 SaxonHE9.3Nを使用する: C:¥Program Files¥Saxonica¥SaxonHE9.3N¥bin> query -qs: "/ */entry [string-length(。)> =/*/entry/string-length(。 )] [1] "-s:sample.xml は、 <?xml version =" 1.0 "encoding =" UTF-8 "を返します。
追加された 著者 travis,
しかし、このクエリは、 C:¥Program Files¥Saxonica¥SaxonHE9.3N¥bin> query -qs: "// entry [not(string-length(child :: string-length(子:: text())<=次の::エントリ/文字列の長さ(子:text())<= previous :: entry/string-length(child :: text())) <?xml version = "1.0" encoding = "UTF-8"?> Nunc suscipit lobortis arcu、nec adipiscing not()を削除して符号を逆転させると、動作しません。
追加された 著者 travis,
ああ、それは今働く、ありがとう!
追加された 著者 travis,
@travis:良いキャッチ - 私は今夜少しオフフォーカスです。修正されました。
追加された 著者 Dimitre Novatchev,
@ lwburk:ありがとう。はい、代表的なテストデータの欠如は私たちが持っている最大の問題の1つです。この問題を解決する1つの方法は、最初の質問を一般化し、それをさまざまな視点で見ることです。
追加された 著者 Dimitre Novatchev,
@travis:申し訳ありませんが、これは不本意な間違いであったに違いありません。私はすぐに私の答えを修正しました - してください、今それを試してください。
追加された 著者 Dimitre Novatchev,
@travis:私は個人的に更新された答えが正しいことを確認しました。答えに最大文字列長の entry 要素を選択するためにXPath 2.0式を使用するXSLTコードを追加して出力しました。
追加された 著者 Dimitre Novatchev,
@travis:あなたは大歓迎です。この問題を指摘してくれてありがとう。時には、非常にまれに、私は夜遅く、朝早く、または仕事を急いで質問に答えています。これはスリップしている可能性があります:)
追加された 著者 Dimitre Novatchev,
""(string-length(someNodeSet)はこのノードセットの最初のノードにのみ適用されます) " - 私は愚かな間違いを犯し、あまりにも少数のテストケースでだまされました。これは最高の答えです。
追加された 著者 Wayne Burkett,