【问题标题】:XPath to return string concatenation of qualifying child node valuesXPath 返回合格子节点值的字符串连接
【发布时间】:2010-11-27 02:24:20
【问题描述】:

任何人都可以建议一种 XPath 表达式格式,该格式返回一个字符串值,其中包含一个元素的某些合格子节点的连接值,但忽略其他:

<div>
    This text node should be returned.
    <em>And the value of this element.</em>
    And this.
    <p>But this paragraph element should be ignored.</p>
</div>

返回值应该是单个字符串:

This text node should be returned. And the value of this element. And this.

这可以在单个 XPath 表达式中实现吗?

谢谢。

【问题讨论】:

    标签: xpath string-concatenation


    【解决方案1】:

    这个效果很好:

    作为上下文使用/div/:

    text() | em/text()
    

    或者不使用上下文:

    /div/text() | /div/em/text()
    

    如果你想连接前两个字符串,使用这个:

    concat(/div/text(), /div/em/text())
    

    【讨论】:

    • 谢谢。这是朝着正确方向迈出的良好一步。但我看不到如何连接结果。当我将它包装在对 string() 函数的调用中时,它只返回第一个选定节点的值。
    • 是的,正如您所看到的,我的解决方案与“正确”解决方案的作用相同.. ¬¬ 您可以 concat(...) 节点,但是,您不会看到第三个“文本”。试试这个: concat(/div/text(), /div/em/text())
    【解决方案2】:
    /div//text()
    

    双斜线强制提取文本而不考虑中间节点

    【讨论】:

    • 这有点相关并且很容易知道。谢谢。
    【解决方案3】:

    在 XPath 1.0 中:

    你可以使用

    /div//text()[not(parent::p)]
    

    捕获想要的文本节点。连接本身不能在 XPath 1.0 中完成,我建议在宿主应用程序中完成。

    【讨论】:

    • 谢谢 - 你说得对。我刚刚阅读了 XPath 参考,发现所有字符串函数都隐式地在节点集中的第一个节点上工作,因此无法将选择和连接结合起来。
    • 可爱优雅。你真好!
    【解决方案4】:

    在 XPath 2.0 中

    string-join(/*/node()[not(self::p)], '')

    【讨论】:

    • 但是像string-join(normalize-space(//a[@class="title"]//text()))这样的string-join()不支持嵌套函数
    • @SIslam,这不是“嵌套函数”问题,而只是 normalize-space() 采用单个参数——而不是序列。您可以改用此表达式:string-join(//a[@class='title']/normalize-space())。当然,你必须在string-join()的调用中添加第二个参数
    【解决方案5】:

    您也可以使用 for-each 循环并将值组合到这样的变量中

    <xsl:variable name="newstring">
        <xsl:for-each select="/div//text()">
          <xsl:value-of select="."/>
        </xsl:for-each>
      </xsl:variable>
    

    【讨论】:

    • 不相关。海报询问了 XQuery。
    【解决方案6】:

    如果你想要除 p 之外的所有孩子,你可以尝试以下...

        string-join(//*[name() != 'p']/text(), "")
    

    返回...

    This text node should be returned.
    And the value of this element.
    And this.
    

    【讨论】:

      【解决方案7】:

      我知道这有点晚了,但我认为我的回答可能仍然相关。我最近遇到了类似的问题。而且因为我在Python 3.6中使用scrapy,它不支持xpath 2.0,所以我无法使用几个在线答案中建议的string-join函数。

      我最终找到了一个简单的解决方法(如下所示),我在任何 stackoverflow 答案中都没有看到,这就是我分享它的原因。

      temp_selector_list = response.xpath('/div')
      string_result = [''.join(x.xpath(".//text()").extract()) for x in temp_selector_list]
      

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2015-06-21
        • 2016-11-27
        • 1970-01-01
        • 2011-05-13
        • 2023-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-25
        相关资源
        最近更新 更多