简体   繁体   中英

Create a transformation (XSL) to modify a heat (WiX) output

I'm trying to transform the output heat (WiX)

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="WINSERVINSTALLDIR">
            <Component Id="Dak.IPTV2.Service.exe" 
                       Guid="DC327EF4-0456-4031-A520-46F5D8EE7930">
                <File Id="Dak.IPTV2.Service.exe" KeyPath="yes" 
                      Source="$(var.winServDir)\Dak.IPTV2.Service.exe" />
            </Component>
        </DirectoryRef>
    </Fragment>
    <Fragment>
        <ComponentGroup Id="WINSERV">
            <ComponentRef Id="Dak.IPTV2.Service.exe" />
        </ComponentGroup>
    </Fragment>
</Wix>

Using this XSLT file

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

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

  <!-- except "Component" nodes -->
  <xsl:template match="Component">
    <xsl:copy>
      <xsl:attribute name="Id">
        <xsl:value-of select="concat('WinServ_', @Id)"/>
      </xsl:attribute>
      <xsl:apply-templates select="*" />

    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

But it does not work. What I want is to append a prefix (WinServ_ for example) to the value of the Id attribute for all Component nodes. After applying the XSLT the output is the same as input.

What is wrong?

Best regards

Final Solution Thanks to Tim and Tom I finally get what I want: an XSL transformation to append to some outputs form Heat (WiX) to avoid Id conflicts. This is the final XSLT file (there are other similar)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
  <xsl:output method="xml" indent="yes"/>

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

  <!-- except "Component" nodes -->
  <xsl:template match="wix:Component|wix:ComponentRef|wix:File">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:attribute name="Id">
        <xsl:value-of select="concat('WebApp_', @Id)"/>
      </xsl:attribute>
      <xsl:apply-templates select="child::*" />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

You have not accounted for the wix namespace in your XSLT. In the wix XML, all elements are in a namespace, as declared by the default namespace element on the root element.

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">

Your XSLT is currently trying to match a Component element in no namespace, and won't match the Component element in the input XML which is in the namespace.

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
      xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
  <xsl:output method="xml" indent="yes"/>

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

  <!-- except "Component" nodes -->
  <xsl:template match="wix:Component">
    <xsl:copy>
      <xsl:attribute name="Id">
        <xsl:value-of select="concat('WinServ_', @Id)"/>
      </xsl:attribute>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Note the use of the wix prefix is arbitrary here. It can be anything you choose, just so long as the namespace uri matches.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM