I have a problem finding duplicate components using xslt. I am using heat to harvest 2 Projects. These projects share some references (.dll files). Now heat creates 2 Fragments
The ConfiguratorFiles.wxs gets created first and use a totaly basic filter:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="service-search" match="wix:Component[contains(wix:File/@Source, '.pdb')]" use="@Id" />
<xsl:template match="wix:Component[key('service-search', @Id)]"/>
<xsl:template match="wix:ComponentRef[key('service-search', @Id)]" />
The output is totally fine, as i really want every dll to be copied and filter out pdb files.
The Problem arises, when creating the ServiceFiles.wxs file. I just can't figure out how to check wether an element exists in the first wxs file.
That link provided the information, that i could embed a C# function, to execute some logic. That seems like a neat trick to me, but still i don't know how to search the contents of the other file.
The ServiceFilter.xslt is nearly the same as the ConfiguratorFiles.xslt, but i also filter out .exe Files, as i handle them manually
<!--Match and ignore .pdb files-->
<xsl:key name="service-search" match="wix:Component[contains(wix:File/@Source, '.pdb')]" use="@Id" />
<xsl:template match="wix:Component[key('service-search', @Id)]"/>
<xsl:template match="wix:ComponentRef[key('service-search', @Id)]"/>
<!--Match and ignore .exe files-->
<xsl:key name="exe-search" match="wix:Component[contains(wix:File/@Source, '.exe')]" use="@Id"/>
<xsl:template match="wix:Component[key('exe-search', @Id)]"/>
<xsl:template match="wix:ComponentRef[key('exe-search', @Id)]"/>
I have the following component in both (ConfiguratorFiles.wxs and ServiceFiles.wxs). This results in an error, that is why i need to filter duplicates.
<Component Id="Foo.Base.dll" Guid="*">
<File Id="Foo.Base.dll" KeyPath="yes" Source="$(var.Foo.DSI.Configurator.TargetDir)\Foo.Base.dll" />
</Component>
How to write a filter "ServiceFilter.xslt" that filters duplicates, so that ServiceFiles.wxs does not contain a file, that is contained in ConfiguratorFiles.wxs ?
What i'm trying right now is to use a C# Method. Now i only need to figure out, how to get all Components in the first file to fill out the FindDuplicate method, as it currently filters everything :)
<!--Match and ignore duplicate components-->
<xsl:key name="duplicate-search" match="wix:Component[user:FindDuplicate(wix:File/@Source)]" use="@Id"/>
<xsl:template match="wix:Component[key('duplicate-search', @Id)]"/>
<xsl:template match="wix:ComponentRef[key('duplicate-search', @Id)]"/>
<msxsl:script language="C#" implements-prefix="user">
<![CDATA[
public bool FindDuplicate(string name){
return true;
}
]]>
</msxsl:script>
The Solution was pretty easy.
I do now create 2 separate MSI-Files. One which installs the configurator and One installs the Service. These 2 MSI-Files are created in 2 different WiX projects, so the problem of duplicated entries won't appear anymore.