删除节点或 children 基于另一个 child
Remove node or children based on another child
我正在使用 Wix Head 来获取带有一些 third-party 依赖项的输出目录,但我仍在尝试围绕 XSLT 转换进行思考。
我大致有:
<Wix>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Component Id="1">
<File Source="Valid.dll"/>
<RegistryValue />
</Component>
<Component Id="2">
<File Source="Valid.pdb"/>
</Component>
<Component Id="3">
<File Source="XML.dll"/>
<RegistryValue />
<RegistryValue />
<RegistryValue />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="Published">
<Component Id="1" />
<Component Id="2" />
<Component Id="3" />
</ComponentGroup>
</Fragment>
</Wix>
我想要的:
<Wix>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER>
<Component Id="1">
<File Source="Valid.dll"/>
<RegistryValue />
</Component>
<Component Id="3">
<File Source="XML.dll"/>
</Component>
<DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="Published">
<Component Id="1" />
<Component Id="3" />
</ComponentGroup>
</Fragment>
</Wix>
到目前为止,我的 XSLT 模板并不适用于彼此。他们做自己的事。它们在 wix 命名空间中,但我针对这个问题对其进行了简化。
<xsl:stylesheet version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="pdbs" match="Component[contains(File/@Source, 'pdb')]" use="@Id"/>
<xsl:key name="unneededRegistry" match="Component[not(contains(File/@Source, 'Valid'))]" use="@Id"/>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Remove PDBs -->
<xsl:template match="*[self::Component or self::ComponentRef][key('pdbs',@Id']"/>
<!-- Remove everything but file in non-core dlls -->
<xsl:template match="Component[key('unneededRegistry',@Id)]">
<xsl:copy>
<xsl:apply-template select="@*|File"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我觉得我快要得到它了,但我已经尝试了很多都无济于事。
我需要删除文件中所有带有 pdb 的组件,并删除所有不是有效节点上的文件的节点。
下面是修改后的样式sheet.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="pdbs" match="Component[contains(File/@Source, 'pdb')]" use="@Id"/>
<!-- I have removed this key
<xsl:key name="unneededRegistry" match="Component[not(contains(File/@Source, 'Valid'))]" use="@Id"/>
-->
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Remove PDBs,
have included a predicate here instead of a key
-->
<xsl:template match="*[self::Component or self::ComponentRef]
[contains(File/@Source, 'pdb')]"/>
<!-- Remove everything but file in non-core dlls,
have included a predicate here instead of a key
-->
<xsl:template match="DirectoryRef/Component[not(contains(File/@Source, 'Valid'))]">
<xsl:copy>
<xsl:apply-templates select="@*|File"/>
</xsl:copy>
</xsl:template>
<!-- added a rule here to delete target Component nodes -->
<xsl:template match="ComponentGroup/Component[key('pdbs', @Id)]"/>
</xsl:stylesheet>
查看实际效果 here。
我正在使用 Wix Head 来获取带有一些 third-party 依赖项的输出目录,但我仍在尝试围绕 XSLT 转换进行思考。
我大致有:
<Wix>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER">
<Component Id="1">
<File Source="Valid.dll"/>
<RegistryValue />
</Component>
<Component Id="2">
<File Source="Valid.pdb"/>
</Component>
<Component Id="3">
<File Source="XML.dll"/>
<RegistryValue />
<RegistryValue />
<RegistryValue />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="Published">
<Component Id="1" />
<Component Id="2" />
<Component Id="3" />
</ComponentGroup>
</Fragment>
</Wix>
我想要的:
<Wix>
<Fragment>
<DirectoryRef Id="INSTALLFOLDER>
<Component Id="1">
<File Source="Valid.dll"/>
<RegistryValue />
</Component>
<Component Id="3">
<File Source="XML.dll"/>
</Component>
<DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="Published">
<Component Id="1" />
<Component Id="3" />
</ComponentGroup>
</Fragment>
</Wix>
到目前为止,我的 XSLT 模板并不适用于彼此。他们做自己的事。它们在 wix 命名空间中,但我针对这个问题对其进行了简化。
<xsl:stylesheet version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="pdbs" match="Component[contains(File/@Source, 'pdb')]" use="@Id"/>
<xsl:key name="unneededRegistry" match="Component[not(contains(File/@Source, 'Valid'))]" use="@Id"/>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Remove PDBs -->
<xsl:template match="*[self::Component or self::ComponentRef][key('pdbs',@Id']"/>
<!-- Remove everything but file in non-core dlls -->
<xsl:template match="Component[key('unneededRegistry',@Id)]">
<xsl:copy>
<xsl:apply-template select="@*|File"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我觉得我快要得到它了,但我已经尝试了很多都无济于事。 我需要删除文件中所有带有 pdb 的组件,并删除所有不是有效节点上的文件的节点。
下面是修改后的样式sheet.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="pdbs" match="Component[contains(File/@Source, 'pdb')]" use="@Id"/>
<!-- I have removed this key
<xsl:key name="unneededRegistry" match="Component[not(contains(File/@Source, 'Valid'))]" use="@Id"/>
-->
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Remove PDBs,
have included a predicate here instead of a key
-->
<xsl:template match="*[self::Component or self::ComponentRef]
[contains(File/@Source, 'pdb')]"/>
<!-- Remove everything but file in non-core dlls,
have included a predicate here instead of a key
-->
<xsl:template match="DirectoryRef/Component[not(contains(File/@Source, 'Valid'))]">
<xsl:copy>
<xsl:apply-templates select="@*|File"/>
</xsl:copy>
</xsl:template>
<!-- added a rule here to delete target Component nodes -->
<xsl:template match="ComponentGroup/Component[key('pdbs', @Id)]"/>
</xsl:stylesheet>
查看实际效果 here。