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

如何遍历XML文件为重复特定标签添加序号以保证唯一性?

问题

现有一个较大的studentinfo.xml文件,需要遍历该文件,对每个stu:StudentScreening节点下的重复st:name标签添加递增序号,使每个标签名称唯一。

原始XML示例

<?xml version="1.0" encoding="UTF-8"?>
<stu:StudentBreakdown>
<stu:Studentdata>
    <stu:StudentScreening>
        <st:name>Sam Davies</st:name>
        <st:age>15</st:age>
        <st:hair>Black</st:hair>
        <st:eyes>Blue</st:eyes>
        <st:grade>10</st:grade>
        <st:teacher>Draco Malfoy</st:teacher>
        <st:dorm>Innovation Hall</st:dorm>
        <st:name>Master Splinter</st:name>
    </stu:StudentScreening>
    <stu:StudentScreening>
        <st:name>Cassie Stone</st:name>
        <st:age>14</st:age>
        <st:hair>Science</st:hair>
        <st:grade>9</st:grade>
        <st:teacher>Luna Lovegood</st:teacher>
        <st:name>Kelly Clarkson</st:name>
    </stu:StudentScreening>
    <stu:StudentScreening>
        <st:name>Derek Brandon</st:name>
        <st:age>17</st:age>
        <st:eyes>green</st:eyes>
        <st:teacher>Ron Weasley</st:teacher>
        <st:dorm>Hogtie Manor</st:dorm>
        <st:name>Miley Cyrus</st:name>
    </stu:StudentScreening>
</stu:Studentdata>
</stu:StudentBreakdown>

期望输出XML示例

<?xml version="1.0" encoding="UTF-8"?>
<stu:StudentBreakdown>
<stu:Studentdata>
    <stu:StudentScreening>
        <st:name0>Sam Davies</st:name0>
        <st:age>15</st:age>
        <st:hair>Black</st:hair>
        <st:eyes>Blue</st:eyes>
        <st:grade>10</st:grade>
        <st:teacher>Draco Malfoy</st:teacher>
        <st:dorm>Innovation Hall</st:dorm>
        <st:name1>Master Splinter</st:name1>
        <st:name2>Peter Griffin</st:name2>
        <st:name3>Louis Griffin</st:name3>
    </stu:StudentScreening>
    <stu:StudentScreening>
        <st:name0>Cassie Stone</st:name0>
        <st:age>14</st:age>
        <st:hair>Science</st:hair>
        <st:grade>9</st:grade>
        <st:teacher>Luna Lovegood</st:teacher>
        <st:name1>Kelly Clarkson</st:name1>
        <st:name2>Stewie Griffin</st:name2>
    </stu:StudentScreening>
    <stu:StudentScreening>
        <st:name0>Derek Brandon</st:name0>
        <st:age>17</st:age>
        <st:eyes>green</st:eyes>
        <st:teacher>Ron Weasley</st:teacher>
        <st:dorm>Hogtie Manor</st:dorm>
        <st:name1>Miley Cyrus</st:name1>
    </stu:StudentScreening>
</stu:Studentdata>
</stu:StudentBreakdown>

解决方案

方法1:使用Python的lxml库(高效处理大文件)

针对大文件,采用迭代解析方式避免内存过载,代码如下:

from lxml import etree

# 替换为实际XML文件中的命名空间URI
namespaces = {'stu': 'http://example.com/stu', 'st': 'http://example.com/st'}

input_path = 'studentinfo.xml'
output_path = 'modified_studentinfo.xml'

parser = etree.iterparse(input_path, events=('start', 'end'))
root = None

with open(output_path, 'wb') as out_file:
    for event, elem in parser:
        if event == 'start' and root is None:
            root = elem
            out_file.write(b'<?xml version="1.0" encoding="UTF-8"?>\n')
            out_file.write(etree.tostring(root, encoding='utf-8', xml_declaration=False, with_tail=False))
        elif event == 'end':
            if elem.tag == etree.QName(namespaces['stu'], 'StudentScreening'):
                name_elements = elem.findall('st:name', namespaces=namespaces)
                for idx, name_elem in enumerate(name_elements):
                    new_tag = etree.QName(namespaces['st'], f'name{idx}')
                    name_elem.tag = new_tag
                out_file.write(etree.tostring(elem, encoding='utf-8', xml_declaration=False, with_tail=True))
                elem.clear()
                while elem.getprevious() is not None:
                    del elem.getparent()[0]
            elif elem.tag != root.tag:
                out_file.write(etree.tostring(elem, encoding='utf-8', xml_declaration=False, with_tail=True))
                elem.clear()
                while elem.getprevious() is not None:
                    del elem.getparent()[0]
    out_file.write(b'</' + root.tag.encode('utf-8') + b'>\n')

执行前需安装lxml:pip install lxml,注意替换代码中的命名空间URI为实际值。

方法2:使用XSLT转换

编写XSLT样式表批量处理,样式表代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:stu="http://example.com/stu" xmlns:st="http://example.com/st">

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="stu:StudentScreening/st:name">
        <xsl:element name="st:name{position()-1}" namespace="http://example.com/st">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

以xsltproc工具为例,执行转换的命令:

xsltproc -o output.xml transform.xsl studentinfo.xml

需替换样式表中的命名空间URI为实际值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:35:16