Cel
Cel

Reputation: 6659

Remove non-matching parent elements in XSL

Source XML

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

Dysfunctional XSLT Stub

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

Desired XML Output

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

Answers (1)

Pavel Veller
Pavel Veller

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

Related Questions