You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用XPath实现按divider分组提取相邻<p>元素集合?

按分组提取

元素的XPath方案

核心思路

无需硬编码节点位置,通过每个

元素的前置关联关系或分隔节点的区间范围动态分组,适配任意数量的节点。

方案1:XPath 2.0+(原生支持分组)

如果你的XPath引擎支持2.0及以上版本(如Saxon、XQuery处理器),可直接利用循环和节点位置运算符实现:

let $root := //root,
    $dividers := ($root/divider, $root/node()[last()])
order by $dividers/position()
for $i in 1 to count($dividers)
return 
  if ($i = 1) then
    $root/p[not(preceding-sibling::divider)]
  else
    $root/p[preceding-sibling::divider[1] = $dividers[$i-1] and . << $dividers[$i]]

逻辑说明

  1. 收集所有节点和文档末尾节点作为分隔边界
  2. 遍历每个边界区间,提取对应范围内的

    元素

  3. 单独处理第一个区间(无前置的

    )

方案2:XPath 1.0 + 宿主语言(以Python为例)

XPath 1.0不支持原生循环和分组,需结合宿主语言逻辑实现,以下是基于Python lxml库的示例:

步骤分解

  1. 获取所有分隔节点
//divider
  1. 分区间提取

  • 提取第一个之前的

    :

//p[not(preceding-sibling::divider)]
  • 提取两个之间的

    (需传入当前和下一个作为参数):

following-sibling::p[preceding-sibling::divider[1] = $current_div and following-sibling::divider[1] = $next_div]
  • 提取最后一个之后的

    :

following-sibling::p[preceding-sibling::divider[1] = $last_div]

完整代码示例

from lxml import etree

# 示例XML结构
xml_content = """
<root>
  <p>第一组段落1</p>
  <p>第一组段落2</p>
  <divider/>
  <p>第二组段落1</p>
  <divider/>
  <p>第三组段落1</p>
  <p>第三组段落2</p>
</root>
"""

tree = etree.fromstring(xml_content)
dividers = tree.xpath("//divider")
result_groups = []

# 处理第一组(无前置分隔符的段落)
first_group = tree.xpath("//p[not(preceding-sibling::divider)]")
if first_group:
    result_groups.append([elem.text.strip() for elem in first_group])

# 处理分隔符之间的段落组
for idx, curr_div in enumerate(dividers):
    next_div = dividers[idx+1] if idx+1 < len(dividers) else None
    if next_div:
        group = curr_div.xpath(
            "following-sibling::p[preceding-sibling::divider[1] = $curr and following-sibling::divider[1] = $next]",
            curr=curr_div, next=next_div
        )
    else:
        # 处理最后一个分隔符后的段落
        group = curr_div.xpath(
            "following-sibling::p[preceding-sibling::divider[1] = $curr]",
            curr=curr_div
        )
    if group:
        result_groups.append([elem.text.strip() for elem in group])

print(result_groups)
# 输出: [['第一组段落1', '第一组段落2'], ['第二组段落1'], ['第三组段落1', '第三组段落2']]

关键细节

  • 用preceding-sibling::divider[1]定位每个

    的最近前置分隔符,完全避免硬编码位置

  • XPath 2.0+方案更简洁,适合无需宿主语言介入的场景
  • XPath 1.0方案兼容性更强,适配大多数旧版XML解析库

内容的提问来源于stack exchange,提问作者James Baker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 11:07:07