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

基于Python与LXML:如何在特定上下文修改XML元素属性

基于上下文条件修改XML元素属性

需求说明

需要处理结构如下的XML元素:

<tok tag1="blah1" tag2="blah2" tag3="blah3">TEXT1</tok> 
<tok tag1="blahA" tag2="blahB" tag3="blahC">TEXT2</tok>
<tok tag1="blahX" tag2="blahY" tag3="blahZ">TEXT3</tok>

此前已实现单一条件的属性修改逻辑:

def xml_change(root_element):
    for el in root.xpath('//tok'):        
        if el.get('tag1') == "blah1":
            el.set('tag1', 'Blah1-TEXT1')
            el.set('tag2', 'Blah2-TEXT1')

现在需要实现更复杂的规则:仅当某个<tok>元素的紧邻前一个<tok>的tag1属性为blah1,且紧邻后一个<tok>的tag2属性为blahY时,将该元素的tag1改为newattrib。例如在以下XML中,仅TEXT5对应的元素需要修改:

<tok tag1="blah1" tag2="blah2" tag3="blah3">TEXT1</tok> 
<tok tag1="blahA" tag2="blahB" tag3="blahC">TEXT2</tok>
<tok tag1="blahA" tag2="blahB" tag3="blahC">TEXT3</tok>
<tok tag1="blah1" tag2="blah2" tag3="blah3">TEXT4</tok> 
<tok tag1="blahA" tag2="blahB" tag3="blahC">TEXT5</tok>
<tok tag1="blahX" tag2="blahY" tag3="blahZ">TEXT6</tok>

目标修改结果:

<tok tag1="blah1" tag2="blah2" tag3="blah3">TEXT1</tok> 
<tok tag1="blahA" tag2="blahB" tag3="blahC">TEXT2</tok>
<tok tag1="blahA" tag2="blahB" tag3="blahC">TEXT3</tok>
<tok tag1="blah1" tag2="blah2" tag3="blah3">TEXT4</tok> 
<tok tag1="newattrib" tag2="blahB" tag3="blahC">TEXT5</tok>
<tok tag1="blahX" tag2="blahY" tag3="blahZ">TEXT6</tok>

解决方案

方法1:使用XPath直接定位目标元素

利用XPath的兄弟节点轴,直接筛选出符合前后上下文条件的<tok>节点,再修改属性:

def xml_change(root):
    # XPath表达式:匹配前一个兄弟tag1为blah1、后一个兄弟tag2为blahY的tok元素
    target_elements = root.xpath('//tok[preceding-sibling::tok[1]/@tag1="blah1" and following-sibling::tok[1]/@tag2="blahY"]')
    for el in target_elements:
        el.set('tag1', 'newattrib')

XPath表达式解释:

  • preceding-sibling::tok[1]:当前节点的紧邻前一个兄弟节点([1]限定为直接前序节点,而非所有前序兄弟)
  • following-sibling::tok[1]:当前节点的紧邻后一个兄弟节点
  • 组合条件:同时满足前兄弟的tag1为blah1,后兄弟的tag2为blahY

方法2:遍历节点时检查前后元素

如果需要更灵活的逻辑处理,可以先获取所有<tok>节点的列表,再逐个检查前后节点的属性:

def xml_change(root):
    tok_list = root.xpath('//tok')
    # 跳过第一个和最后一个节点(无完整前后兄弟)
    for i in range(1, len(tok_list)-1):
        current = tok_list[i]
        prev = tok_list[i-1]
        next_el = tok_list[i+1]
        
        if prev.get('tag1') == 'blah1' and next_el.get('tag2') == 'blahY':
            current.set('tag1', 'newattrib')

注意事项:

  • 遍历范围从索引1到len(tok_list)-2,避免访问不存在的前后节点
  • 这种方式适合需要在检查上下文时执行额外操作的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 04:24:33