【问题标题】:How do I select an XML node with the longest child #text node value with XPath?如何使用 XPath 选择具有最长子#text 节点值的 XML 节点?
【发布时间】:2011-12-16 22:02:02
【问题描述】:

在使用此查询之前,我已经使用 XPath 选择了具有最大整数 id 值的节点:

//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()))]

但它返回的是一堆节点而不是一个。

示例 XML:

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

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

【问题讨论】:

    标签: xml xpath textnode


    【解决方案1】:

    无法使用单个 XPath 1.0 表达式选择所需元素,因为在 XPath 1.0 中,无法将函数应用于所有选定节点(string-length(someNodeSet) 仅应用于该节点集的第一个节点)。另一个原因是在 XPath 1.0 中无法命名和引用范围变量。

    在 XPath 2.0 中这是微不足道的

    /*/entry[not(string-length(.) &lt; /*/entry/string-length(.))]
    

    上面选择了所有entry元素,其字符串值的长度是最大的。

    /*/entry[not(string-length(.) &lt; /*/entry/string-length(.))] [1]
    

    上面选择第一个(按文档顺序)entry 元素。

    基于 XSLT 2.0 的验证

    这种转变:

    <xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
     <xsl:template match="/">
      <xsl:sequence select=
       "/*/entry[not(string-length(.) &lt; /*/entry/string-length(.))]"/>
     </xsl:template>
    </xsl:stylesheet>
    

    应用于提供的 XML 文档时

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

    选择字符串长度最大的entry元素(本例中只有一个)并输出选择的元素

    <entry>Nunc suscipit lobortis arcu, nec adipiscing libero bibendum nec.</entry>
    

    【讨论】:

    • 我认为您在第二个查询中遗漏了一些东西,可能是[1]
    • @travis:很好——今晚我有点跑题了。已更正。
    • +1 - "(string-length(someNodeSet) 仅应用于此节点集的第一个节点)" - 我犯了一个愚蠢的错误,然后被愚弄了由于测试用例太少。这是最好的答案。
    • @travis:抱歉,这一定是一个非自愿的错误。我已立即更正了我的答案——请立即尝试。
    • @travis:我个人验证了更新的答案是正确的。在答案中添加了 XSLT 代码,该代码使用 XPath 2.0 表达式来选择具有最大字符串长度的 entry 元素并输出它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多