我有一个.wxs文件,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Directory>
<Directory Id="d1">
<Component Id="c1" ...>
<File Id="f1" KeyPath="yes" ... />
</Component>
<Component Id="c2" ...>
<File Id="f2" KeyPath="yes" ... />
</Component>
<Component Id="c3" ...>
<File Id="f3" KeyPath="yes" ... />
</Component>
</Directory>
<Directory>
<Component>
...
</Directory>
...
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="cg1">
<ComponentRef Id="c1" />
<ComponentRef Id="c2" />
<ComponentRef Id="c3" />
...
</ComponentGroup>
</Fragment>
</Wix>
我想'合并'上面的组件,即我想将文件f2,f3移动到组件c1中,并希望删除组件c2,c3,以及c2,c3的组件引用。在我的实际源代码中,有更多的目录包括组件。我的目的是减少组件的数量,即对于像
这样的任何模式<Directory>
<Component>
<File KeyPath="yes" />
</Component>
<Component>
<File KeyPath="yes" />
</Component>
...
<Component>
<File KeyPath="yes" />
</Component>
</Directory>
我想将它们简化为一个组件(可能是第一个组件),包括许多文件,例如:
<Directory>
<Component>
<File KeyPath="yes" />
<File />
...
<File />
</Component>
</Directory>
我知道不建议在一个组件中包含多个文件,但我想这样做是为了减少卸载时间。现在,我的安装程序需要相当长的时间来卸载,我认为这是因为它有太多的组件(大约20,000个)。
任何帮助将不胜感激。谢谢。
答案 0 :(得分:1)
我认为最简单的方法是使用following-sibling
轴:
<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>
<xsl:template match="wi:Directory">
<xsl:copy>
<!-- Only apply the first <Component> element -->
<xsl:apply-templates select="wi:Component[1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="wi:Component[1]">
<xsl:copy>
<!-- Apply attributes -->
<xsl:apply-templates select="@*"/>
<!-- Apply the <File> element in this <Component> element -->
<xsl:apply-templates select="wi:File"/>
<!-- Apply the <File> elements in all following <Component> siblings -->
<xsl:apply-templates select="following-sibling::wi:Component/wi:File"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Directory Id="d1">
<Component Id="c1">
<File Id="f1" KeyPath="yes"/>
</Component>
<Component Id="c2">
<File Id="f2" KeyPath="yes"/>
</Component>
<Component Id="c3">
<File Id="f3" KeyPath="yes"/>
</Component>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="cg1">
<ComponentRef Id="c1"/>
<ComponentRef Id="c2"/>
<ComponentRef Id="c3"/>
</ComponentGroup>
</Fragment>
</Wix>
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Directory>
<Component Id="c1">
<File Id="f1" KeyPath="yes"/>
<File Id="f2" KeyPath="yes"/>
<File Id="f3" KeyPath="yes"/>
</Component>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="cg1">
<ComponentRef Id="c1"/>
<ComponentRef Id="c2"/>
<ComponentRef Id="c3"/>
</ComponentGroup>
</Fragment>
</Wix>
答案 1 :(得分:0)
这是我的答案。谢谢Eero Helenius。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
exclude-result-prefixes="wix">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:key name="kRemoveComps"
match="wix:Directory/wix:Component[position()>1]" use="@Id" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="wix:Directory">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="wix:Directory" />
<xsl:apply-templates select="wix:Component[1]" />
</xsl:copy>
</xsl:template>
<xsl:template match="wix:Component[1]">
<xsl:copy>
<!-- Attr. -->
<xsl:apply-templates select="@*" />
<!-- File in this Component -->
<xsl:apply-templates select="wix:File" />
<!-- Files in siblings -->
<xsl:apply-templates select="../wix:Component[position()>1]/wix:File" />
</xsl:copy>
</xsl:template>
<xsl:template match="wix:Component[position()>1]/wix:File">
<xsl:copy>
<!-- Removing KeyPath Attr. -->
<xsl:apply-templates select="@*[not(name()='KeyPath')]|node()" />
</xsl:copy>
</xsl:template>
<!-- Removing ComponentRef -->
<xsl:template match="wix:ComponentRef[key('kRemoveComps', @Id)]" />
</xsl:stylesheet>