Skip to main content
 首页 » 编程设计

python之xml 批量文件编辑器按数字递增

2025年05月04日23lvdongjie

我试图在我所有的 xml 文件中以递增方式为 TEXT_VALUE 字段的值添加前缀,只有名为“TRANSL”的标签带有 ID="Example" . 目前我正在手动执行此操作,但由于我有数千个,我认为我应该以编程方式执行此操作。

这是初始版本:

<TRANSL ID="Example"> 
    <TRANSCIPT> 
        <REF_TEXT TEXT_ID="a680" TXT_TM="a24"> 
            <TEXT_VALUE>this is an example</TEXT_VALUE> 
        </REF_TEXT> 
    </TRANSCIPT> 
    <TRANSCIPT> 
        <REF_TEXT TEXT_ID="a681" TXT_TM="a25"> 
            <TEXT_VALUE>another example</TEXT_VALUE> 
        </REF_TEXT> 
    </TRANSCIPT> 
    <TRANSCIPT> 
        <REF_TEXT TEXT_ID="a682" TXT_TM="a26"> 
            <TEXT_VALUE>third example</TEXT_VALUE> 
        </REF_TEXT> 
    </TRANSCIPT> 
</TRANS> 

这是编辑后的样子:

<TRANSL ID="Example"> 
    <TRANSCIPT> 
        <REF_TEXT TEXT_ID="a680" TXT_TM="a24"> 
            <TEXT_VALUE>1-this is an example</TEXT_VALUE> 
        </REF_TEXT> 
    </TRANSCIPT> 
    <TRANSCIPT> 
        <REF_TEXT TEXT_ID="a681" TXT_TM="a25"> 
            <TEXT_VALUE>2-another example</TEXT_VALUE> 
        </REF_TEXT> 
    </TRANSCIPT> 
    <TRANSCIPT> 
        <REF_TEXT TEXT_ID="a682" TXT_TM="a26"> 
            <TEXT_VALUE>3-third example</TEXT_VALUE> 
        </REF_TEXT> 
    </TRANSCIPT> 
</TRANS> 

我怎样才能以编程方式做到这一点?那里有专业的 xml 编辑器吗?如果没有,我该如何在 python、powershell、perl、记事本++ 或任何其他软件中完成?

这是我在 python 中作为记事本++ 插件编写的脚本:

def increment_replace(match): 
    return "<TEXT_VALUE>{}".format(str(int(match.group(1))+1)) 
 
editor.rereplace(r'\<TEXT_VALUE\>', increment_replace) 

但它不起作用...

请您参考如下方法:

获取当前计数/position()的 <TEXT_VALUE>元素可以引用count/position() parent 的<TRANSCIPT>元素。

将此计数传递给后续模板I used the solution from this SO answer并将其方法合并到 身份模板 中,现在传递一个 num包含一些值的参数。 num参数在 <for-each> 中生成循环高于所有 <TRANSCIPT>元素并传递给<apply-templates>在 TEXT_VALUE 中使用的层次结构模板(其他任何地方都被忽略)。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
 
  <!-- modified identity template --> 
  <xsl:template match="node()|@*"> 
    <xsl:param name="num" /> 
    <xsl:copy>   
      <xsl:apply-templates select="node()|@*"> 
        <xsl:with-param name="num" select="$num"/> 
      </xsl:apply-templates> 
    </xsl:copy> 
  </xsl:template> 
 
  <xsl:template match="TRANSL"> 
    <xsl:copy> 
      <xsl:apply-templates select="@*" /> 
      <xsl:for-each select="TRANSCIPT"> 
        <xsl:copy> 
        <xsl:apply-templates> 
          <xsl:with-param name="num" select="position()" /> 
        </xsl:apply-templates> 
        </xsl:copy> 
      </xsl:for-each>     
    </xsl:copy> 
  </xsl:template> 
 
  <xsl:template match="TEXT_VALUE[../../../@ID='Example']">   <!-- added after extension of question --> 
    <xsl:param name="num" /> 
    <xsl:element name="TEXT_VALUE"> 
      <xsl:value-of select="concat($num,'-',text())" /> 
    </xsl:element>         
  </xsl:template> 
 
</xsl:stylesheet> 

编辑:
在评论中扩展要求后,我向 TEXT_VALUE 添加了一个谓词模板修改匹配规则只选择TEXT_VALUE具有 @ID 的元素值为“Example”的属性。