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

使用XSLT将节点移入同级节点为子节点并添加属性(WiX V4)

解决WiX Toolset v4生成.wxs文件的自动修复问题

需求说明

通过调用heat.exe时应用XSLT样式表,自动修复生成的.wxs文件,需完成三项任务:

  • 移除RegistryValue节点
  • 为TypeLib节点添加Language="0"属性
  • 将与File同级的TypeLib节点移入File节点作为子节点

原始生成的XML

<!-- Starting XML -->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
    <Fragment>
        <DirectoryRef />
    </Fragment>
    <Fragment>
        <ComponentGroup>
            <Component>
                <File />
                <RegistryValue />
                <TypeLib>
                    <!-- Child Interface nodes. -->
                </TypeLib>
            </Component>
        </ComponentGroup>
    </Fragment>
</Wix>

期望的目标XML

<!-- Desired XML -->
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
    <Fragment>
        <DirectoryRef />
    </Fragment>
    <Fragment>
        <ComponentGroup>
            <Component>
                <File>
                    <TypeLib Language="0">
                        <!-- Child Interface nodes. -->
                    </TypeLib>
                </File>
            </Component>
        </ComponentGroup>
    </Fragment>
</Wix>

现有未完成需求的XSLT样式表

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

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <!-- Remove the RegistryValue attribute. -->
    <xsl:template match="wix:RegistryValue" />

    <!-- Add the missing Language="0" attribute to the TypeLib component. -->
    <xsl:template match="wix:TypeLib" name="add-language">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="Language">0</xsl:attribute>
            <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>

    <!-- Select the file node and make the typelib node a child. -->
    <xsl:template match="wix:File">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:call-template name="add-language" />
            <!--<xsl:copy-of select="following-sibling::wix:TypeLib[1]" />-->
            <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="wix:TypeLib[preceding-sibling::*[1][self::wix:File]]" />
</xsl:stylesheet>

修正后的完整XSLT样式表

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

    <xsl:output method="xml" indent="yes" />

    <!-- 身份模板:默认复制所有节点和属性 -->
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <!-- 移除RegistryValue节点 -->
    <xsl:template match="wix:RegistryValue" />

    <!-- 为TypeLib节点添加Language="0"属性 -->
    <xsl:template match="wix:TypeLib" name="add-language">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="Language">0</xsl:attribute>
            <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>

    <!-- 处理File节点:将同级的TypeLib移入作为子节点,并应用属性添加模板 -->
    <xsl:template match="wix:File">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <!-- 复制File自身的子节点 -->
            <xsl:apply-templates select="node()" />
            <!-- 选取当前File后续同级的第一个TypeLib,调用add-language模板处理 -->
            <xsl:apply-templates select="following-sibling::wix:TypeLib[1]" mode="move" />
        </xsl:copy>
    </xsl:template>

    <!-- 匹配需要移动的TypeLib,调用add-language模板 -->
    <xsl:template match="wix:TypeLib" mode="move">
        <xsl:call-template name="add-language" />
    </xsl:template>

    <!-- 移除原位置的TypeLib节点 -->
    <xsl:template match="wix:TypeLib[preceding-sibling::wix:File]" />
</xsl:stylesheet>

关键修改说明

  1. 调整File节点模板:在复制File节点时,通过following-sibling::wix:TypeLib[1]选取其后续的第一个TypeLib节点,使用mode="move"调用专门的处理模板,避免和默认TypeLib模板冲突。
  2. 新增move模式模板:专门处理需要移动的TypeLib,调用已有的add-language模板完成属性添加,实现逻辑复用。
  3. 简化TypeLib移除模板:直接匹配所有位于File节点之后的TypeLib节点,移除原位置的节点,避免重复输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:04:57