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

使用XSLT为XML的ComponentDetails标签添加ID并保留子标签

解决XML中为标签添加ID属性且保留子标签的问题

我来帮你梳理这个问题的解决过程——你想要给XML里所有<ComponentDetails>标签添加ID属性,方便后续通过ID定位到对应的Amount和YTDAmount值,但最初的XSLT虽然成功添加了ID,却意外丢失了子标签内容,调整模板匹配路径后就完美解决了这个问题。

示例XML结构

<?xml version="1.0" encoding="UTF-8"?>
<root> 
  <PayrunDetails> 
    <PayrunNumber>000777</PayrunNumber> 
    <PaidDate>2018-05-15</PaidDate> 
  </PayrunDetails> 
  <PayLocation> 
    <LocationCode>ACT</LocationCode> 
    <LocationDescription>ACT</LocationDescription> 
    <CompanyDetails> 
      <CCode>APPLE</CCode> 
      <CName>APPLE Limited</CName> 
      <Payslip> 
        <StaffNumber>12345</StaffNumber> 
        <BankDetails> 
          <BankAccountNo>121212</BankAccountNo> 
        </BankDetails> 
        <PayDetails> 
          <PayType>NORMAL</PayType> 
          <AmountGross>9999</AmountGross> 
          <ComponentDetails> 
            <ComponentType>SALARY</ComponentType> 
            <Amount>1999</Amount> 
            <YTDAmount>10616</YTDAmount> 
          </ComponentDetails> 
          <ComponentDetails> 
            <ComponentType>TAXABLE</ComponentType> 
            <Amount>505</Amount> 
            <YTDAmount>7703</YTDAmount> 
          </ComponentDetails> 
        </PayDetails> 
      </Payslip> 
      <Payslip> 
        <StaffNumber>45555</StaffNumber> 
        <BankDetails> 
          <BankAccountNo>131313</BankAccountNo> 
        </BankDetails> 
        <PayDetails> 
          <PayType>NORMAL</PayType> 
          <AmountGross>9999</AmountGross> 
          <ComponentDetails> 
            <ComponentType>SALARY</ComponentType> 
            <Amount>1999</Amount> 
            <YTDAmount>10616</YTDAmount> 
          </ComponentDetails> 
          <ComponentDetails> 
            <ComponentType>GROSS</ComponentType> 
            <Amount>7305</Amount> 
            <YTDAmount>76703</YTDAmount> 
          </ComponentDetails> 
          <ComponentDetails> 
            <ComponentType>TAXABLE</ComponentType> 
            <Amount>305</Amount> 
            <YTDAmount>6703</YTDAmount> 
          </ComponentDetails> 
        </PayDetails> 
      </Payslip> 
    </CompanyDetails> 
  </PayLocation> 
</root>

初始XSLT(存在子标签丢失问题)

这段代码尝试给所有<ComponentDetails>添加ID,但运行后会丢失子标签内容:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
  <xsl:output omit-xml-declaration="yes" indent="yes"/> 
  <xsl:strip-space elements="*"/> 
  <xsl:template match="node()|@*"> 
    <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
  </xsl:template> 
  <xsl:template match="ComponentDetails"> 
    <xsl:copy> 
      <xsl:attribute name="ID"> 
        <xsl:number/> 
      </xsl:attribute> 
      <xsl:apply-templates select="@*|node()" /> 
    </xsl:copy> 
  </xsl:template> 
</xsl:stylesheet>

修正后的可用XSLT

调整匹配路径为更具体的PayDetails/ComponentDetails,并优化模板顺序后,既能成功添加ID,又完整保留了所有子标签:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="PayDetails/ComponentDetails">
    <xsl:copy>
      <xsl:attribute name="ID">
        <xsl:number/>
      </xsl:attribute>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

关键调整说明

  1. 更精准的匹配路径:将模板匹配从通用的ComponentDetails改为PayDetails/ComponentDetails,确保只处理目标层级下的标签,避免意外影响其他位置的同名标签(如果有的话)。
  2. 模板顺序优化:把针对<ComponentDetails>的具体模板放在通用复制模板前面,让XSLT优先执行具体匹配,保证ID属性被正确添加后,再通过通用模板处理所有子标签和属性,从而完整保留原有内容。

现在你可以通过类似//ComponentDetails[@ID='1']/Amount的XPath表达式,快速定位到对应ID标签下的Amount或YTDAmount值了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:07:54