首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用XML样式表删除与另一个文件中内容匹配的元素。

使用XML样式表删除与另一个文件中内容匹配的元素。
EN

Stack Overflow用户
提问于 2021-09-03 14:22:09
回答 1查看 39关注 0票数 0

我想转换像这样的xml文件:

(input.xml)

代码语言:javascript
复制
<?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)

代码语言:javascript
复制
<Files>
  <File>FileB</File>
  <File>FileC</File>
</Files>

结果应该如下所示:

(output.xml)

代码语言:javascript
复制
<?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)

代码语言:javascript
复制
<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“中的文件如何才能被重新处理呢?下面是我尝试过的,但这不起作用(变量不允许匹配)

代码语言:javascript
复制
<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和一些附加的连接。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-03 16:42:48

在XSLT1.0中这样做所面临的主要障碍是:(a)键不能跨文档工作;(b)不能在匹配模式中使用变量。

也许你可以这样做:

XSLT1.0

代码语言:javascript
复制
<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>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69046468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档