XPath,在至少有一个元素匹配时返回true。

huangapple go评论57阅读模式
英文:

XPath that returns true when at least one element matches

问题

boolean(//*[local-name() = 'Person'][xs:integer(substring(./Age/text(), 1)) >= 18 and xs:integer(substring(./Age/text(), 1)) <= 22])
英文:

Let's assume we have the following XML response:

&lt;People&gt;
    &lt;Person&gt;
        &lt;Age&gt;29&lt;/Age&gt;
    &lt;/Person&gt;
    &lt;Person&gt;
        &lt;Age&gt;25&lt;/Age&gt;
    &lt;/Person&gt;
    &lt;Person&gt;
        &lt;Age&gt;18&lt;/Age&gt;
    &lt;/Person&gt;
    &lt;Person&gt;
        &lt;Age&gt;45&lt;/Age&gt;
    &lt;/Person&gt;
&lt;/People&gt;

I want an xpath 2.0 expression that will return true if there is at least one person with age between 18 and 22.

My current expression is:

boolean(//*:Person[xs:integer(substring(//*[local-name() = &#39;Age&#39;]/text(), 2)) &gt;= 18 and 22 &gt;= xs:integer(substring(//*[local-name() = &#39;Age&#39;]/text(), 2))])

But this expression is not recursive so it produces the following error:

>A sequence of more than one item is not allowed as the first argument of substring() ("29", "25", ...)

Any idea as to how I can achieve what I need?

答案1

得分: 3

在XPath 2.0中,这是 exists(//Person[Age = (18 to 22)])

英文:

In XPath 2.0 this is exists(//Person[Age = (18 to 22)])

答案2

得分: 1

这个XPath,

boolean(/People/Person[Age &gt; 18][Age &lt; 22])

将会返回true,当且仅当至少有一个Person的年龄在18到22之间,不包括边界值。

注意:

  • 如果这个XPath嵌入在XML/XSLT中,请确保使用&amp;lt;代替&lt;
  • 如果要包含边界值,请使用&gt;=和/或&lt;=
  • 除非您试图消除命名空间,否则没有理由使用local-name()*:,在这里命名空间不起作用,而且应该被接受而不是被消除。
英文:

This XPath,

boolean(/People/Person[Age &gt; 18][Age &lt; 22])

will return true iff at least one Person has an age between 18 and 22, exclusive.

Notes:

  • Be sure to use &amp;lt; for &lt; if this XPath is embedded in XML/XSLT.

  • Use &gt;= and/or &lt;= for inclusive endpoints.

  • There is no reason to use local-name() and *: unless you are trying to defeat namespaces, which

    1. are not in play here anyway, but
    2. can and should be accommodated, not defeated.

答案3

得分: 0

这里有一个有点复杂的代码,它使用了 counttranslate

count(//Age[translate(translate(., "1", "X"), "89", "YY") = "XY" or .= "22" or translate(translate(., "2", "X"), "01", "YY") = "XY"]) > 0

22 是一个特殊情况,因为 translate 将其转换为 XX

英文:

here's a twisted one that uses count and translate

count(//Age[translate(translate(., &quot;1&quot;, &quot;X&quot;),&quot;89&quot;,&quot;YY&quot;) = &quot;XY&quot; or .=&quot;22&quot; or translate(translate(., &quot;2&quot;, &quot;X&quot;),&quot;01&quot;,&quot;YY&quot;) = &quot;XY&quot;]) &gt; 0

22 is an special case since translate turns it into XX

huangapple
  • 本文由 发表于 2023年6月1日 23:02:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76383286.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定