【问题标题】:An XPath 1.0 query that handles two cases处理两种情况的 XPath 1.0 查询
【发布时间】:2011-08-09 06:54:41
【问题描述】:

我在 XPaths 方面不是很有经验,但我尝试了很长时间并且搜索了很多,但没有找到解决方案。

我正在从 XHTML 中提取信息,这些信息大多类似于

<html>
    <head></head>
    <body>
        <div class="preamble">
            <p>Some text 1</p>
        </div>
        <h1>Some headline</h1>
        <p>Some other text</p>
    </body>
</html>

我最感兴趣的是序言 div 中包含的文本,它存在于我的大多数文档中。问题是缺少 div,在这些情况下,我想提取 body 标签下的其他文本。

在这种情况下,我想获得“Some text 1”,但如果没有 div,我会接受“Some heading Some other text”之类的。

使用 XPath 2.0 没问题,但情况限制了我使用“核心”1.0 集中的功能。

我的问题是这种行为在一个 XPath 1.0 查询中是否可行,或者我是否应该放弃它?

问候/马格努斯

【问题讨论】:

    标签: java xml xhtml xpath


    【解决方案1】:

    试试这个 XPath:

    //div[@class = 'preamble'] 
        | //body/*[not(preceding-sibling::div[@class = 'preamble']) 
            and not(self::div[@class = 'preamble'])]
    

    【讨论】:

      【解决方案2】:

      由于 XPath 1.0 没有为节点集指定排序,您需要确保您的两种情况是互斥的。

      string( /html/body/div[@class='preamble'] | /html/body[not(div[@class='preamble'])] )
      

      如果您的 XPath 处理器按文档顺序返回节点集,则可以使用更简单的查询:

      string( (/html/body/div[@class='preamble'] | /html/body)[last()] )
      

      【讨论】:

      • @Magnus Nilsson:我同意这个答案是最好的。所以,你需要接受它——在SO,这是表达感激的既定方式。这是通过单击最佳答案旁边的复选标记来完成的。
      【解决方案3】:

      我认为你需要这个 XPath 1.0:

      "/html/body/div[@class='preamble']//text()
      |
      /html/body[not(div/@class='preamble')]//text()"
      

      第一个位置路径选择 div 内的所有文本节点。另一个将选择没有该 div 的正文中的所有文本节点。两者的联合 (|) 将选择想要的文本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多