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

BeautifulSoup替换XML标签失效问题求助

问题:BeautifulSoup的replace_with替换XML标签未生效

我编写了一段BeautifulSoup4代码,用于读取当前目录下的XML文件,找到其中的ccl_tag标签,按照指定顺序重新排列内部的date_tag、req_tag等标签后,尝试用replace_with方法替换原标签。经检查new_ccl内容正确,但替换操作未生效,请问问题出在哪里?

代码如下:

import glob
from bs4 import BeautifulSoup

# get all ccl_tags
# rearrange
# replace current ccl_tag with data replaced
# print to output file

def rearrange_xml(input_file, output_file, tag_ordering):
  # Reading the data inside the xml
  # file to a variable under the name
  # data
  with open(input_file, "r") as f:
     data = f.read()
  
  # Passing the stored data inside
  # the beautifulsoup parser, storing
  # the returned object
  Bs_data = BeautifulSoup(data, "xml")
  
  # Finding all instances of tag
  # `ccl_tag` asign to "ccls"
  ccls = Bs_data.find_all("ccl_tag")
  
  # rearrange the ccl based on the given ordering
  for ccl in ccls:
     # declare new ccl
     new_ccl = BeautifulSoup()
     tags_to_rearrange = []
     # find all tags in tag ordering which are also inside ccl
     for tag_name in tag_ordering:
        tags = ccl.find_all(tag_name)
        tags_to_rearrange.extend(tags)
     # find only the found tags to rearrage and apply to new ccl
     for tag in tags_to_rearrange:
        tag.extract()
        # only add the tags specified
        new_ccl.append(tag)
     print(new_ccl)
     # replace with doesn't work?
     ccl.replace_with(new_ccl)

  print(Bs_data.find("ccl_tag"))
  
  with open(output_file, "w") as file:
     file.write(Bs_data.prettify())

# Get a list of XML files in the same directory


xml_files = glob.glob("*.xml")
   tag_ordering = [
      "date_tag",
      "req_tag",
      "req2_tag",
      "req3_tag"
   ]

# Rearrange each XML file


for input_file in xml_files:
      # don't include output_ files
      if not input_file.startswith("output_"):
         output_file = f"output_{input_file}"
         rearrange_xml(input_file, output_file, tag_ordering)

问题原因

你创建的new_ccl是一个完整的BeautifulSoup文档对象,而非与原标签类型一致的<ccl_tag>标签。

当调用ccl.replace_with(new_ccl)时,你是在用整个文档对象替换原有的<ccl_tag>标签。BeautifulSoup不会自动将文档对象的内容包装成<ccl_tag>,反而会导致XML结构混乱,最终表现为替换未生效。另外,原代码中tag.extract()已经将子标签从原ccl_tag中移除,但后续将这些标签添加到文档对象中,替换后无法保持原有的<ccl_tag>外层结构。


解决方案

需要创建一个新的<ccl_tag>标签(而非文档对象),再将整理好的子标签添加到这个新标签中,最后用新标签替换原标签。

修改后的关键代码片段

for ccl in ccls:
    # 创建新的ccl_tag标签,使用当前文档环境的new_tag方法
    new_ccl = Bs_data.new_tag("ccl_tag")
    tags_to_rearrange = []
    for tag_name in tag_ordering:
        tags = ccl.find_all(tag_name)
        tags_to_rearrange.extend(tags)
    for tag in tags_to_rearrange:
        tag.extract()
        new_ccl.append(tag)
    # 用同类型的新标签替换原标签
    ccl.replace_with(new_ccl)

修改说明

  1. 使用Bs_data.new_tag("ccl_tag")创建的标签属于当前解析的文档环境,避免跨文档对象的兼容性问题。
  2. 新标签与原标签类型完全一致,替换后XML结构保持正确,原有的<ccl_tag>会被替换成包含排序后子标签的新<ccl_tag>。

内容的提问来源于stack exchange,提问作者Prosy A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 14:24:52