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

使用Python合并多SVG文件图层,解决重复层级问题

解决SVG嵌套图层合并问题

问题描述

现有Python代码可合并多个SVG文件,但无法正确处理嵌套图层结构——每个SVG的图层会重复创建(如重复的Layer1),期望将同ID的同层级图层合并,形成统一的嵌套结构。

当前合并后的图层结构

START
-Layer1
--Layer2
---Layer3
----Layer3a
-----PATH
-Layer1
--Layer2
---Layer3
----Layer3b
-----PATH
-Layer1
--Layer2
---Layer2a
----PATH
-Layer1
--Layer2
---Layer2b
----PATH

期望的图层结构

START
-Layer1
--Layer2
---Layer2a
----PATH
---Layer2b
----PATH
---Layer3
----Layer3a
-----PATH
----Layer3b
-----PATH

当前代码

import os
from xml.etree import ElementTree as ET

#SVG files input folder
svg_dir = './Import/'

#New SVG
merged_svg = ET.Element('svg')

#Loop through SVG in folder
for i, filename in enumerate(os.listdir(svg_dir)):

    #Check if SVG ends with "update.svg"
    if filename.endswith('update.svg'):

        #Open SVG and parse content
        svg_path = os.path.join(svg_dir, filename)
        svg_tree = ET.parse(svg_path)

        #Get root element of SVG
        svg_root = svg_tree.getroot()
        

        #Check if root element exists
        if svg_root is not None:
            if i == 0:
                #Add root element of first SVG
                merged_svg = svg_root
            else:
                #Merge root element of other SVG to the first
                for attr, value in svg_root.items():
                    merged_svg.set(attr, value)

                #Loop through each child element in root
                for child in svg_root:
                    print(child)

                    if isinstance(child, ET.Element):

                        #Find element with same ID in merged SVG file
                        existing_element = merged_svg.find('.//*[@id="%s"]' % child.get('id'))
                        if existing_element is not None:

                            #If element already exists - append to sub-child
                            print("element already exists - append to sub-child")
                            for sub_child in child:
                                if isinstance(sub_child, ET.Element):
                                    existing_element.append(sub_child)
                        else:
                            #If the element does not exist 
                            print("element does not exist - append to child")
                            merged_svg.append(child)

# Write the merged SVG to a file
merged_svg_file = open('./Export/COMBINED.svg', 'w')
merged_svg_file.write(ET.tostring(merged_svg).decode())
merged_svg_file.close()

修改后的代码

原代码仅处理了根节点下的第一层元素,未递归处理嵌套的子图层。添加递归函数merge_elements,实现逐层查找同ID元素并合并子内容:

import os
from xml.etree import ElementTree as ET

def merge_elements(parent, new_element):
    """递归合并嵌套元素:查找父节点下同ID的元素,存在则合并子元素,不存在则添加"""
    elem_id = new_element.get('id')
    if not elem_id:
        # 无ID的元素直接添加
        parent.append(new_element)
        return

    # 在当前父节点的直接子元素中查找同ID元素(确保层级匹配)
    existing_element = None
    for child in parent:
        if child.get('id') == elem_id:
            existing_element = child
            break

    if existing_element is not None:
        # 合并属性(新属性覆盖旧属性)
        for attr, value in new_element.items():
            existing_element.set(attr, value)
        # 递归处理子元素
        for sub_child in new_element:
            merge_elements(existing_element, sub_child)
    else:
        # 元素不存在,直接添加到当前父节点
        parent.append(new_element)

# SVG文件输入文件夹
svg_dir = './Import/'
merged_svg = None

# 遍历文件夹中的SVG文件
for filename in os.listdir(svg_dir):
    if filename.endswith('update.svg'):
        svg_path = os.path.join(svg_dir, filename)
        svg_tree = ET.parse(svg_path)
        svg_root = svg_tree.getroot()

        if svg_root is None:
            continue

        if merged_svg is None:
            # 初始化合并后的SVG为第一个文件的根节点
            merged_svg = svg_root
        else:
            # 合并根节点属性
            for attr, value in svg_root.items():
                merged_svg.set(attr, value)
            # 递归合并根节点下的所有子元素
            for child in svg_root:
                merge_elements(merged_svg, child)

# 写入合并后的SVG文件
if merged_svg is not None:
    with open('./Export/COMBINED.svg', 'w') as f:
        f.write(ET.tostring(merged_svg).decode())

关键修改点

  • 递归合并逻辑:新增merge_elements函数,逐层处理嵌套元素,确保同ID的同层级图层被合并,避免跨层级错误。
  • 层级匹配:在当前父节点的直接子元素中查找同ID元素,而非全局查找,保证图层结构的正确性。
  • 属性合并:合并元素时用新元素的属性覆盖旧元素的同名属性,保留最新配置。
  • 代码优化:使用with语句管理文件,避免资源泄漏;调整初始化逻辑,代码更简洁清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:13:10