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

如何用XSLT修改XML文件中ComponentType标签的嵌套结构?

如何用XSLT调整XML的标签嵌套结构与属性转换?

我需要调整现有XML的标签嵌套结构:将ComponentDetails节点下的Amount、YTDAmount标签移入ComponentType标签内,并将ComponentType原文本内容转为其ID属性。

原XML内容:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
  <PayrunDetails> 
    <PayrunNumber>000777</PayrunNumber> 
  </PayrunDetails> 
  <PayLocation> 
    <LocationCode>ACT</LocationCode> 
    <LocationDescription>ACT</LocationDescription> 
    <CompanyDetails> 
      <CName>APPLE Limited</CName> 
      <Payslip> 
        <StaffNumber>12345</StaffNumber> 
        <PayDetails> 
          <AmountGross>9999</AmountGross> 
          <ComponentDetails> 
            <ComponentType>SALARY</ComponentType> 
            <Amount>1999</Amount> 
            <YTDAmount>10616</YTDAmount> 
          </ComponentDetails> 
          <ComponentDetails> 
            <ComponentType>SALARY</ComponentType> 
            <Amount>7305</Amount> 
            <YTDAmount>76703</YTDAmount> 
          </ComponentDetails> 
        </PayDetails> 
      </Payslip> 
    </CompanyDetails> 
  </PayLocation> 
</root>

期望输出XML:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
  <PayrunDetails> 
    <PayrunNumber>000777</PayrunNumber> 
  </PayrunDetails> 
  <PayLocation> 
    <LocationCode>ACT</LocationCode> 
    <LocationDescription>ACT</LocationDescription> 
    <CompanyDetails> 
      <CName>APPLE Limited</CName> 
      <Payslip> 
        <StaffNumber>12345</StaffNumber> 
        <PayDetails> 
          <AmountGross>9999</AmountGross> 
          <ComponentDetails> 
            <ComponentType ID="SALARY"> 
              <Amount>1999</Amount> 
              <YTDAmount>10616</YTDAmount> 
            </ComponentType> 
          </ComponentDetails> 
          <ComponentDetails> 
            <ComponentType ID="TAX"> 
              <Amount>7305</Amount> 
              <YTDAmount>76703</YTDAmount> 
            </ComponentType> 
          </ComponentDetails> 
        </PayDetails> 
      </Payslip> 
    </CompanyDetails> 
  </PayLocation> 
</root>

作为XSLT新手,我不清楚如何编写实现该需求的代码,恳请指导。


解决方案:XSLT代码实现

以下是满足你需求的XSLT样式表,我会逐部分解释它的作用:

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

  <!-- 身份转换模板:默认复制所有节点和属性,保留不需要修改的内容 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 处理ComponentType元素:将文本内容转为ID属性,并嵌入Amount和YTDAmount -->
  <xsl:template match="ComponentType">
    <!-- 创建带ID属性的ComponentType元素,ID值为原文本内容 -->
    <ComponentType ID="{.}">
      <!-- 选择当前ComponentDetails下的Amount和YTDAmount,作为子节点嵌入 -->
      <xsl:apply-templates select="../Amount | ../YTDAmount"/>
    </ComponentType>
  </xsl:template>

  <!-- 隐藏原位置的Amount和YTDAmount:避免重复输出 -->
  <xsl:template match="ComponentDetails/Amount | ComponentDetails/YTDAmount"/>

</xsl:stylesheet>

代码解释:

  1. 身份转换模板:这是XSLT的基础模板,它会原样复制XML中所有未被其他模板匹配的节点和属性,确保你的XML中不需要修改的部分(比如PayrunNumber、StaffNumber等)保持不变。
  2. ComponentType处理模板:
    • 匹配所有ComponentType元素,创建一个新的ComponentType元素。
    • 使用{.}获取原ComponentType的文本内容(比如SALARY),将其作为ID属性的值。
    • 通过../Amount | ../YTDAmount选择当前ComponentType的父节点(ComponentDetails)下的Amount和YTDAmount元素,将它们作为子节点嵌入到新的ComponentType中。
  3. 隐藏原位置的Amount/YTDAmount:匹配ComponentDetails下的这两个元素,模板内没有任何输出,这样它们就不会在原来的位置重复出现,只会出现在新的ComponentType嵌套结构里。

使用方法:

你可以将上述XSLT保存为.xsl文件,然后使用XSLT处理器(比如Saxon、Xalan)或者在线XSLT测试工具,将原XML和XSLT文件输入,即可得到期望的输出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:08:35