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

如何使用XSLT 1.0仅复制XML属性的部分内容到新文档

问题解决:XSLT 1.0处理PRODUCT元素属性需求

需求

  • 对所有PRODUCT元素的name属性,仅保留点号(.)之前的内容
  • 将code属性值为12的PRODUCT节点,移除原code属性,添加delivery="done"属性

输入XML

<START> 
    <LIST>
        <PRODUCT name="ELEMENT1.HKL" code="12" >
            <SPEC>
                <available>yes</available>
            </SPEC>
        </PRODUCT>
        
        <PRODUCT name="ELEMENT2.HKL" code="14" >
            <SPEC>
                <available>yes</available>
            </SPEC>
        </PRODUCT>
        
    </LIST>
</START>

期望输出XML

<?xml version="1.0" encoding="UTF-8"?><START>
   <LIST>
       <PRODUCT delivery="done" name="ELEMENT1">
           <SPEC>
               <available>yes</available>
           </SPEC>
       </PRODUCT>
       <PRODUCT code="14" name="ELEMENT2">
           <SPEC>
               <available>yes</available>
           </SPEC>
       </PRODUCT>
   </LIST>
</START>

原代码问题分析

原XSLT存在两处核心问题:

  1. 处理code="12"的模板中,substring-before(., '.')的目标是当前@code属性值(即12),而非父节点的@name属性,导致无法正确截取name内容
  2. 未处理所有PRODUCT的name属性,仅试图在code="12"的模板中修改name,遗漏了其他PRODUCT的需求

修正后的XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <!-- 身份模板:复制所有未被特殊模板匹配的节点和属性 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 处理所有PRODUCT的name属性:截取点号前的内容 -->
    <xsl:template match="PRODUCT/@name">
        <xsl:attribute name="name">
            <xsl:choose>
                <!-- 如果name包含点号,截取前半部分;否则保留原内容 -->
                <xsl:when test="contains(., '.')">
                    <xsl:value-of select="substring-before(., '.')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:attribute>
    </xsl:template>

    <!-- 处理code属性值为12的情况:替换为delivery="done" -->
    <xsl:template match="PRODUCT/@code[.='12']">
        <xsl:attribute name="delivery">done</xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

修改说明

  1. 新增专门匹配PRODUCT/@name的模板,统一处理所有PRODUCT的name属性,确保无论code值如何,都能正确截取点号前的内容
  2. 修正PRODUCT/@code[.='12']的模板:仅生成delivery="done"属性,不再处理name(name交给专门模板),同时原code属性会因被该模板匹配而不再被身份模板复制,达到移除原code属性的效果
  3. 保留身份模板,确保其他未修改的节点和属性正常复制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:33:25