【问题标题】:Cannot modify the Name attribute value of Directoryref/Directory element after Wix harvesting with Heat tool使用 Heat 工具收集 Wix 后无法修改 Directoryref/Directory 元素的 Name 属性值
【发布时间】:2020-04-29 14:13:47
【问题描述】:

在 WiX Toolset Heat 工具从源目录中获取组件后,它会生成一个 wxs 文件,其中包含例如以下内容。

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="TARGETDIR">
            <Directory Id="dirGeneratedID1" Name="MySourceDirName">
                <Component Id="cmpGeneratedID1" Guid="*">
                    <File Id="filGeneratedID1" KeyPath="yes" Source="$(var.SourceRootDir)\File1.dll" />
                </Component>
                <Component Id="cmpGeneratedID2" Guid="*">
                    <File Id="filGeneratedID2" KeyPath="yes" Source="$(var.SourceRootDir)\File2.dll" />
                </Component>
                <Directory Id="dirGeneratedID2" Name="MyNestedDirName">
                    <Component Id="cmpGeneratedID3" Guid="*">
                        <File Id="filGeneratedID3" KeyPath="yes" Source="$(var.SourceRootDir)\MyNestedDirName\File3.dll" />
                    </Component>
                </Directory>
            </Directory>
        </DirectoryRef>
    </Fragment>
</Wix>

我的任务是仅更改父目录元素的名称属性值。也就是说,将 /Wix/Fragment/DirectoryRef/Directory[@Name='MySourceDirName'] 元素的 Name 属性值从“MySourceDirName”更改为“MY_RENAMED_SOURCE_DIR_NAME”,因此我得到以下结果。

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="TARGETDIR">
            <Directory Id="dirGeneratedID1" Name="MY_RENAMED_SOURCE_DIR_NAME">
                <Component Id="cmpGeneratedID1" Guid="*">
                    <File Id="filGeneratedID1" KeyPath="yes" Source="$(var.SourceRootDir)\File1.dll" />
                </Component>
                <Component Id="cmpGeneratedID2" Guid="*">
                    <File Id="filGeneratedID2" KeyPath="yes" Source="$(var.SourceRootDir)\File2.dll" />
                </Component>
                <Directory Id="dirGeneratedID2" Name="MyNestedDirName">
                    <Component Id="cmpGeneratedID3" Guid="*">
                        <File Id="filGeneratedID3" KeyPath="yes" Source="$(var.SourceRootDir)\MyNestedDirName\File3.dll" />
                    </Component>
                </Directory>
            </Directory>
        </DirectoryRef>
    </Fragment>
</Wix>

由于生成 wxs 文件的是 Heat 工具,并且源目录名称为“MySourceDirName”,因此生成的目录元素名称属性等于“MySourceDirName”,稍后需要将其通过 XSL 转换为我想要的新文件夹名称'MY_RENAMED_SOURCE_DIR_NAME'。

我使用以下 XSLT,但它不起作用,并且出现错误“DirectoryRef 元素包含意外的属性 'Name'。”

<?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="*"/>

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

    <xsl:template match="/wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Directory">

      <xsl:attribute name="Name">
        <xsl:choose>
          <xsl:when test=". = 'MySourceDirName'">
            <xsl:text>MY_RENAMED_SOURCE_DIR_NAME</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="." />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>

    </xsl:template>
</xsl:stylesheet

XSLT 之后生成的 wxs 文件变成了错误且不完整的文件:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="SciemetricDIR" Name="" />
    </Fragment>
</Wix>

如果我更改我的 XSLT 并添加 xsl:copy 以恢复如下内容(这里我只显示整个 XSLT 内容的影响规则)

    <xsl:template match="/wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Directory">

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

      <xsl:attribute name="Name">
        <xsl:choose>
          <xsl:when test=". = 'MySourceDirName'">
            <xsl:text>MY_RENAMED_SOURCE_DIR_NAME</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="." />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>

    </xsl:template>

然后我收到此错误:“将转换 C:\path-to-my-transform-file\massageAfterHeatHarvesting.xsl 应用到收获的 WiX 时出错:属性和命名空间节点无法在文本、注释之后添加到父元素, pi,或子元素节点已经添加。MySoulutionName heat.exe 0 "

我的 XSLT 有什么问题?如果我清楚地将 Directory 子元素定位在它下面,为什么它会触及 DirectoryRef 父元素?非常感谢任何支持。提前致谢。

【问题讨论】:

    标签: xslt wix


    【解决方案1】:

    XSLT 处理器遇到 Directory 元素,然后按照指定创建一个 Name 属性而不是其他任何东西(它停止)。

    尝试改变

    <xsl:template match="/wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Directory">
    

    <xsl:template match="/wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Directory/@Name">
    

    实际上,将条件作为谓词移动到匹配属性中会更好:

    <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>
    

    【讨论】:

    • 非常感谢@wasmachien,最后一个选项对我来说效果很好。
    猜你喜欢
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    相关资源
    最近更新 更多