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

WiX Heat生成wxs后修改Directory Name属性的XSLT问题排查

Fixing XSLT Transformation Issues for WiX Heat-Generated Files

Let's break down what's going wrong with your XSLT and fix it step by step.

What's Wrong with Your Original XSLT?

First Attempt: Missing Element Copy & Incorrect Context

Your first template matches the target <Directory> element but only outputs a Name attribute without copying the element itself. Here's the breakdown of the issues:

  • Without <xsl:copy> for the matched <Directory> element, the XSLT processor drops that element entirely.
  • The Name attribute you're trying to create ends up attached to the parent <DirectoryRef> element (since that's the active parent context when the template runs), which is invalid—<DirectoryRef> shouldn't have a Name attribute, hence the error "The DirectoryRef element contains an unexpected attribute 'Name'."
  • All child content of the original <Directory> (components, nested directories) gets lost because you never apply templates to preserve them.

Second Attempt: Attribute Order Violation

Your second fix adds <xsl:copy> to preserve the <Directory> element and its content, but you're trying to add the Name attribute after processing the element's children. XML requires all attributes to be declared before any child elements or text nodes. Adding an attribute post-child-nodes triggers the error "Attribute and namespace nodes cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added."

The Correct XSLT Solution

Instead of matching the entire <Directory> element, target specifically its Name attribute. This lets you modify just that attribute while leaving everything else intact via the identity template.

Here's the working XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" exclude-result-prefixes="wix">
    <xsl:output omit-xml-declaration="no" indent="yes" />
    <xsl:strip-space elements="*"/>

    <!-- Identity template: copy all nodes/attributes by default -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <!-- Target only the Name attribute of the specific Directory element -->
    <xsl:template match="/wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Directory/@Name[.='MySourceDirName']">
        <xsl:attribute name="Name">MY_RENAMED_SOURCE_DIR_NAME</xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

How This Works:

  1. The identity template handles copying every node and attribute in the input XML exactly as-is—this preserves all your components, nested directories, and other attributes (like Id on the Directory element).
  2. The second template targets only the Name attribute of the exact <Directory> element you want to modify (the direct child of <DirectoryRef> with Name="MySourceDirName").
  3. When that attribute is matched, we replace it with a new Name attribute set to your desired value, while leaving everything else untouched.

Alternative Approach (Matching the Directory Element)

If you prefer to match the entire <Directory> element instead, adjust the template to process attributes first (modifying Name) then handle child nodes:

<xsl:template match="/wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Directory">
    <xsl:copy>
        <!-- Process attributes first: modify Name if needed -->
        <xsl:apply-templates select="@*" />
        <!-- Then process child nodes -->
        <xsl:apply-templates select="node()" />
    </xsl:copy>
</xsl:template>

<!-- Separate template to modify the Name attribute -->
<xsl:template match="/wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Directory/@Name[.='MySourceDirName']">
    <xsl:attribute name="Name">MY_RENAMED_SOURCE_DIR_NAME</xsl:attribute>
</xsl:template>

This also works because it ensures attributes are processed before child nodes, avoiding the order violation error.

Either solution will correctly rename the target directory's Name attribute while preserving all other content in your WiX file.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:37:45