Reputation: 6659
Component
elements and their corresponding ComponentRef
elements, where the Component
child element File
attribute Source
is NOT a dll
file?Source
string value i.e. {substring(wix:File/@Source, string-length(wix:File/@Source) - 2)}='dll'
returns true for Source
values that contain dll
Component
elements (with their children) as well as the corresponding last two ComponentRef
elements (mapped by Id
attribute)?<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="TARGETFOLDER">
<Component Id="cmpA733DB49D89AC9CEA2EDFAAEE51992E7" Guid="{F3412A8F-5718-45AB-9E6F-7B802BCC0EED}">
<File Source="$(var.WixSlave.TargetDir)\protobuf-net.dll" Id="fil910D6DB28382BAB5A9DF0ACBD5095ADE" KeyPath="yes" />
</Component>
<Component Id="cmpF1D751B9621E283AD7BDAA8BC6997338" Guid="{20C09DBB-C8D6-43CF-A9D6-C823850F86F6}">
<File Source="$(var.WixSlave.TargetDir)\client.wyc" Id="fil7454A527FA7C3918A537EB96235C9F5F" KeyPath="yes" />
</Component>
<Component Id="cmp8CDA926DD93F7CEFBF8FFF444D5828F4" Guid="{2243D9D8-C172-4FFE-AEBE-43659294E55D}">
<File Source="$(var.WixSlave.TargetDir)\protobuf-net.pdb" Id="fil3EA19C07C51C4E31D37065B3A8620713" KeyPath="yes" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="Dlls">
<ComponentRef Id="cmpA733DB49D89AC9CEA2EDFAAEE51992E7" />
<ComponentRef Id="cmpF1D751B9621E283AD7BDAA8BC6997338" />
<ComponentRef Id="cmp8CDA926DD93F7CEFBF8FFF444D5828F4" />
</ComponentGroup>
</Fragment>
</Wix>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="wix:File[{substring(wix:File/@Source, string-length(wix:File/@Source) - 2)}!='dll']"/>
</xsl:stylesheet>
This XSLT does not work in many ways, firstly the second match
complains, and I'm not sure what is wrong with the expression..
Even if that worked, how would you always retain DirectoryRef
while removing the mismatching Component
and child File
elements?
Removing the corresponding ComponentRef
elements is missing altogether?
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="TARGETFOLDER">
<Component Id="cmpA733DB49D89AC9CEA2EDFAAEE51992E7" Guid="{F3412A8F-5718-45AB-9E6F-7B802BCC0EED}">
<File Source="$(var.WixSlave.TargetDir)\protobuf-net.dll" Id="fil910D6DB28382BAB5A9DF0ACBD5095ADE" KeyPath="yes" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="Dlls">
<ComponentRef Id="cmpA733DB49D89AC9CEA2EDFAAEE51992E7" />
</ComponentGroup>
</Fragment>
</Wix>
Upvotes: 0
Views: 855
Reputation: 6115
Here's how I would go about it:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="component-id" match="//wix:Component[substring(wix:File/@Source, string-length(wix:File/@Source) - 2) != 'dll']" use="@Id"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="wix:Component[@Id = key('component-id', @Id)/@Id]"/>
<xsl:template match="wix:ComponentRef[@Id = key('component-id', @Id)/@Id]"/>
</xsl:stylesheet>
The idea is rather simple. Tell XSLT processor to build an index of those Component nodes we want removed and then suppress the xsl:copy
with a matching template.
Upvotes: 2