使用Beautiful Soup 4渲染inline自闭和元素 转换img为Confluence宏问题
问题根因
BeautifulSoup 默认的 HTML 解析与渲染规则仅将 W3C 标准定义的原生空元素(如 <img>、<br>、<input> 等)识别为自闭合标签。<ri:attachment> 是 Confluence 自定义命名空间标签,不在默认自闭合标签列表内,因此渲染时会被拆分为独立的开标签和闭标签。
解决方案
两步调整即可实现预期输出:
- 直接构造 Tag 对象替代字符串解析,避免解析阶段丢失自闭合属性
- 自定义 HTML 渲染器,将
<ri:attachment>加入自闭合标签列表
完整修改后代码
import os from bs4 import BeautifulSoup from bs4.formatter import HTMLFormatter # 自定义渲染器,添加Confluence自闭合标签 class ConfluenceHTMLFormatter(HTMLFormatter): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.self_closing_tags.add("ri:attachment") def transform_img_to_confluence(soup): def get_image_tag(image_name): # 直接构造标签对象,稳定性高于字符串解析 ac_image = soup.new_tag("ac:image", **{ "ac:align": "center", "ac:layout": "center" }) ri_attachment = soup.new_tag("ri:attachment", **{ "ri:filename": image_name, "ri:version-at-save": "1" }) # 显式标记为可自闭合元素 ri_attachment.can_be_empty_element = True ac_image.append("\n") ac_image.append(ri_attachment) ac_image.append("\n") return ac_image for img in soup.find_all('img'): path = img['src'] image_name = os.path.basename(path) image_tag = get_image_tag(image_name) img.replace_with(image_tag) # 调用逻辑 html_string = ''' <p> <img src="path/to/file.jpg" /> </p> ''' soup = BeautifulSoup(html_string, "html.parser") transform_img_to_confluence(soup) # 用自定义渲染器输出,指定缩进为4空格 formatter = ConfluenceHTMLFormatter(indent=4) print(soup.decode(formatter=formatter))
输出结果
<p> <ac:image ac:align="center" ac:layout="center"> <ri:attachment ri:filename="file.jpg" ri:version-at-save="1" /> </ac:image> </p>
内容的提问来源于stack exchange,提问作者Adharsh M
相关产品推荐
相关产品推荐

