I use Heat from Wix toolset to generate components for my installer but few of my installers are a Per-User and such i cannot use Heat's Autogenerate Guids. I can randomly generate a GUID but i don't want that because of components rules.
So I have an XML with list of files that should be included in the Installations in different structure than the generated one into which i have added static guids for each file.
What i want to do is match the filename
between my XML and generated XML and insert the GUID into my generated XML.
Here is a sample of the xml without any transformation:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="Dir_Sample">
<Directory Id="Folder1" Name="Folder1">
<Component Id="NewTextFile0.txt" Guid="PUT-GUID-HERE">
<File Id="NewTextFile0.txt" KeyPath="yes" Source="$(var.sample)\Folder1\NewTextFile0.txt" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="CG_Sample">
<ComponentRef Id="NewTextFile0.txt" />
</ComponentGroup>
</Fragment>
</Wix>
Here is my custom XML with GUIDs for each File:
<?xml version="1.0" encoding="utf-8"?>
<FileSystemList>
<File Path="\Programs\Folder1\NewTextFile0.txt" Guid="52B62A6E-DD87-424A-8296-3AA00E74AEF8" />
</FileSystemList>
So i want Guid="PUT-GUID-HERE
" be replaced with Guid="52B62A6E-DD87-424A-8296-3AA00E74AEF8"
when the filename and preferably the parent folder matches on both XMLs.
I'm trying to understand XSL but all i'm able to achieve is hair loss. I and my remaining hair will appreciate any help.
Update:
Matching between these two xml files should be performed on Source
of the first file and Path
of the second file.
Source="$(var.sample)\Folder1\NewTextFile0.txt"
The file name (NewTextFile0.txt) and the parent folder (Folder1) together are unique in a project.
The same goes for Path="\Programs\Folder1\NewTextFile0.txt"
File name and parent folder being unique.
Try something like:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wi="http://schemas.microsoft.com/wix/2006/wi">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- insert GUID -->
<xsl:template match="wi:Component/@Guid">
<xsl:variable name="path" select="concat(../../@Name, '\', ../@Id)" />
<xsl:attribute name="Guid">
<xsl:value-of select="document('FileList.xml')/FileSystemList/File[contains(@Path, $path)]/@Guid"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
To base the match on the contents of Component/File/@Source
, change the definition of the $path
variable to:
<xsl:variable name="path" select="substring-after(../wi:File/@Source, ')')" />
This is assuming that anything in the Source
attribute that comes after the first ")" is part of the path stored in the other file.