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

如何用Python重命名XSLT中的重复变量声明及引用

解决XSLT重复变量声明问题的Python脚本

问题背景

我有一段Altova MapForce生成的XSLT 2.0代码,其中变量var287___as_double被重复声明引发语法错误。需要通过Python修改该文件,可选两种处理方式:

  1. 将AL506C标签下的重复变量var287___as_double重命名(如改为var287___as_double2),并同步修改该标签内的所有引用
  2. 直接对AL506C标签下的所有变量进行重命名,彻底避免重复冲突

原代码示例

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template name="SDEV:SDEV_NCTS_down_fillUCRC547"/>
        <xsl:for-each select="($var292_CD___C)]">
            <AL586B xmlns="AL586B" >
                <xsl:variable name="var288_cur" as="node()" select="."/>
                <xsl:variable name="var287___as_double" as="xs:double" select="xs:double('6')"/>
            </AL586B>
        </xsl:for-each>
        <xsl:for-each select="(./ns0:AL586B)">
            <AL506C xmlns="AL506C">
                <xsl:attribute name="xsi:schemaLocation" namespace="http://www.w3.org/2001/XMLSchema-instance"/>
                <xsl:variable name="var287___as_double" as="xs:double" select="xs:double('6')"/>
                <xsl:variable name="var1_preparationDateAndTi_as_string" as="xs:string" select="xs:string(xs:dateTime(fn:string($var287___as_double)))"/>
            </AL506C>
        </xsl:for-each>
</xsl:stylesheet>

修改后代码示例(方式1)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template name="SDEV:SDEV_NCTS_down_fillUCRC547"/>
        <xsl:for-each select="($var292_CD___C)]">
            <AL586B xmlns="AL586B" >
                <xsl:variable name="var288_cur" as="node()" select="."/>
                <xsl:variable name="var287___as_double" as="xs:double" select="xs:double('6')"/>
            </AL586B>
        </xsl:for-each>
        <xsl:for-each select="(./ns0:AL586B)">
            <AL506C xmlns="AL506C">
                <xsl:attribute name="xsi:schemaLocation" namespace="http://www.w3.org/2001/XMLSchema-instance"/>
                <xsl:variable name="var287___as_double2" as="xs:double" select="xs:double('6')"/>
                <xsl:variable name="var1_preparationDateAndTi_as_string" as="xs:string" select="xs:string(xs:dateTime(fn:string($var287___as_double2)))"/>
            </AL506C>
        </xsl:for-each>
</xsl:stylesheet>

Python解决方案

依赖准备

首先安装XML解析库:

pip install lxml

方式1:重命名指定重复变量

该脚本会定位AL506C标签下的var287___as_double变量,将其重命名为var287___as_double2,并同步替换该标签内的所有引用:

from lxml import etree

# 定义命名空间
NS_MAP = {
    'xsl': 'http://www.w3.org/1999/XSL/Transform',
    'al506c': 'AL506C'
}

def fix_duplicate_variable(xslt_path, output_path):
    # 读取XSLT文件
    tree = etree.parse(xslt_path)
    root = tree.getroot()

    # 找到所有AL506C节点
    al506c_nodes = root.xpath('//al506c:AL506C', namespaces=NS_MAP)

    for node in al506c_nodes:
        # 找到目标变量声明
        target_var = node.xpath('./xsl:variable[@name="var287___as_double"]', namespaces=NS_MAP)
        if not target_var:
            continue
        target_var = target_var[0]
        
        # 重命名变量
        old_name = target_var.get('name')
        new_name = f"{old_name}2"
        target_var.set('name', new_name)

        # 替换当前AL506C节点内所有对该变量的引用($varxxx格式)
        for elem in node.xpath('.//*', namespaces=NS_MAP):
            # 处理select属性
            if 'select' in elem.attrib:
                elem.attrib['select'] = elem.attrib['select'].replace(f"${old_name}", f"${new_name}")
            # 处理文本内容
            if elem.text:
                elem.text = elem.text.replace(f"${old_name}", f"${new_name}")

    # 保存修改后的文件
    tree.write(output_path, encoding='utf-8', xml_declaration=True, pretty_print=True)

# 使用示例
fix_duplicate_variable('input.xsl', 'fixed_input.xsl')

方式2:重命名AL506C下所有变量

该脚本会给AL506C标签下的所有变量名添加后缀_al506c,彻底避免变量重复冲突:

from lxml import etree

NS_MAP = {
    'xsl': 'http://www.w3.org/1999/XSL/Transform',
    'al506c': 'AL506C'
}

def rename_all_al506c_variables(xslt_path, output_path):
    tree = etree.parse(xslt_path)
    root = tree.getroot()
    al506c_nodes = root.xpath('//al506c:AL506C', namespaces=NS_MAP)

    for node in al506c_nodes:
        # 收集当前节点下的所有变量及其新名称
        var_mapping = {}
        variables = node.xpath('./xsl:variable', namespaces=NS_MAP)
        for var in variables:
            old_name = var.get('name')
            new_name = f"{old_name}_al506c"
            var.set('name', new_name)
            var_mapping[old_name] = new_name

        # 替换所有变量引用
        for elem in node.xpath('.//*', namespaces=NS_MAP):
            if 'select' in elem.attrib:
                select_val = elem.attrib['select']
                for old, new in var_mapping.items():
                    select_val = select_val.replace(f"${old}", f"${new}")
                elem.attrib['select'] = select_val
            if elem.text:
                text_val = elem.text
                for old, new in var_mapping.items():
                    text_val = text_val.replace(f"${old}", f"${new}")
                elem.text = text_val

    tree.write(output_path, encoding='utf-8', xml_declaration=True, pretty_print=True)

# 使用示例
rename_all_al506c_variables('input.xsl', 'fixed_input_all.xsl')

注意事项

  • 脚本使用lxml处理XML,相比正则表达式能更安全地处理XML结构,避免破坏XSLT语法
  • 若XSLT中存在复杂的变量引用(如嵌套在字符串或其他表达式中),可根据实际情况调整替换逻辑
  • 处理前建议备份原XSLT文件,避免数据丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:05:05