我想转换像这样的xml文件:
(input.xml)
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef>
<Component Id="c1">
<File Source="!(PublishDir)\FileA" />
</Component>
<Component Id="c2">
<File Source="!(PublishDir)\FileB" />
</Component>
<Component Id="c3">
<File Source="!(PublishDir)\FileC" />
</Component>
<Component Id="c4">
<File Source="!(PublishDir)\FileD" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup>
<ComponentRef Id="c1" />
<ComponentRef Id="c2" />
<ComponentRef Id="c3" />
<ComponentRef Id="c4" />
</ComponentGroup>
</Fragment>
</Wix>这是热量的简化输出,wix ()收割机。但这不应该有什么区别。
从原始xml中删除一些不需要的文件(包括组件和ComponentRef标记)。其中一些文件是预先知道的(FileA),有些文件名在这样的文件中:
(filelist.xml)
<Files>
<File>FileB</File>
<File>FileC</File>
</Files>结果应该如下所示:
(output.xml)
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef>
<Component Id="c4">
<File Source="!(PublishDir)\FileD" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup>
<ComponentRef Id="c4" />
</ComponentGroup>
</Fragment>
</Wix>删除预先知道的文件很简单,以下是我到目前为止所拥有的:
(stylesheet.xsl)
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!-- identity transform -->
<xsl:template match="@*|*">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="*" />
</xsl:copy>
</xsl:template>
<xsl:output method="xml" indent="yes" />
<!-- remove files -->
<xsl:key name="file-search" match="wix:Component[substring(wix:File/@Source, string-length(wix:File/@Source) - 4) = 'FileA']" use="@Id"/>
<xsl:template match="wix:Component[key('file-search', @Id)]" />
<xsl:template match="wix:ComponentRef[key('file-search', @Id)]" />
</xsl:stylesheet>但是,"filelist.xml“中的文件如何才能被重新处理呢?下面是我尝试过的,但这不起作用(变量不允许匹配)
<xsl:variable name="filelist" select="document('filelist.xml')"/>
<xsl:key name="file-search" match="wix:Component[contains($filelist, substring-after(wix:File/@Source, '\'))]" use="@Id"/>XSLT1.0解决方案更好,因为工具支持它,但我也可以使用XSLT2.0和一些附加的连接。
发布于 2021-09-03 16:42:48
在XSLT1.0中这样做所面临的主要障碍是:(a)键不能跨文档工作;(b)不能在匹配模式中使用变量。
也许你可以这样做:
XSLT1.0
<xsl:stylesheet version="1.0"
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="component-by-filename" match="wix:Component" use="substring-after(wix:File/@Source, '\')" />
<xsl:variable name="exclude-ids" select="key('component-by-filename', 'FileA')/@Id | key('component-by-filename', document('filelist.xml')/Files/File)/@Id "/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="wix:DirectoryRef | wix:ComponentGroup">
<xsl:copy>
<xsl:apply-templates select="*[not(@Id = $exclude-ids)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>https://stackoverflow.com/questions/69046468
复制相似问题