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

如何通过XSLT复制Wix的ComponentGroup节点并修改目标属性

问题:修改Wix XML复制的ComponentGroup中第一个ComponentRef的Id

我需要复制Wix XML里的ComponentGroup节点,修改新节点的Id为AnotherGroup,同时要把复制得到的ComponentGroup里第一个ComponentRef的Id改成AnotherCptRefId。

原始XML:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <ComponentGroup Id="SomeGroup">
      <ComponentRef Id="cmp4CFDF03BB139F024CF278CD5B0CE2D89" />
      <ComponentRef Id="cmp8ACD64282EEF7EAC19C62C7B2AFACA09" />
    </ComponentGroup>
  </Fragment>
</Wix>

我之前已经实现了复制ComponentGroup并修改新节点Id的XSLT代码:

<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"
                xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
                xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <xsl:output method="xml" indent="yes" />
  
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match='wix:Wix/wix:Fragment/wix:ComponentGroup'>
    <!--the original-->
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
    <!--duplicate--> 
    <xsl:copy>
      <xsl:attribute name="Id">AnotherGroup</xsl:attribute>
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

期望输出:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <ComponentGroup Id="SomeGroup">
      <ComponentRef Id="cmp4CFDF03BB139F024CF278CD5B0CE2D89" />
      <ComponentRef Id="cmp8ACD64282EEF7EAC19C62C7B2AFACA09" />
    </ComponentGroup>
    <ComponentGroup Id="AnotherGroup">
      <ComponentRef Id="AnotherCptRefId" />
      <ComponentRef Id="cmp8ACD64282EEF7EAC19C62C7B2AFACA09" />
    </ComponentGroup>  
  </Fragment>
</Wix>

请问该如何修改XSLT代码实现这个需求?


解决方案

修改后的XSLT代码如下:

<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"
                xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
                xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <xsl:output method="xml" indent="yes" />
  
  <xsl:strip-space elements="*"/>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match='wix:Wix/wix:Fragment/wix:ComponentGroup'>
    <!-- 保留原始节点 -->
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
    <!-- 复制并修改后的节点 --> 
    <xsl:copy>
      <xsl:attribute name="Id">AnotherGroup</xsl:attribute>
      <!-- 传递参数标记这是复制的组 -->
      <xsl:apply-templates select="node()">
        <xsl:with-param name="isDuplicateGroup" select="true()"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <!-- 匹配复制组里的第一个ComponentRef,修改其Id -->
  <xsl:template match="wix:ComponentRef[1]">
    <xsl:param name="isDuplicateGroup"/>
    <xsl:copy>
      <xsl:choose>
        <xsl:when test="$isDuplicateGroup">
          <xsl:attribute name="Id">AnotherCptRefId</xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="@*"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

关键改动说明:

  1. 在复制ComponentGroup节点时,通过<xsl:with-param>传递参数isDuplicateGroup,标记当前是复制出来的组,让后续模板知道需要特殊处理子节点。
  2. 添加专门匹配第一个ComponentRef的模板,根据传入的参数判断场景:
    • 如果是复制组的第一个ComponentRef,直接替换其Id属性为目标值。
    • 否则保留原有属性,不做修改。

这样既能保留原始XML的完整结构,又能精准修改复制组内指定节点的属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:32:52