0

我正在尝试从下面的 XML 中删除具有扩展名为“config”的 File 子级的 Component 元素。我已经设法完成了这部分,但我还需要删除与这些组件具有相同“Id”值的匹配 ComponentRef 元素。

<Fragment>
  <DirectoryRef Id="MyWebsite">
    <Component Id="Comp1">
      <File Source="Web.config" />
    </Component>
    <Component Id="Comp2">
      <File Source="Default.aspx" />
    </Component>
  </DirectoryRef>
</Fragment>
<Fragment>
  <ComponentGroup Id="MyWebsite">
    <ComponentRef Id="Comp1" />
    <ComponentRef Id="Comp2" />
  </ComponentGroup>
</Fragment>

基于其他 SO 答案,我提出了以下 XSLT 来删除这些 Component 元素:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="Component[File[substring(@Source, string-length(@Source)- string-length('config') + 1) = 'config']]" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

不幸的是,这不会删除匹配的 ComponentRef 元素(即那些具有相同“Id”值的元素)。XSLT 将删除 ID 为“Comp1”的组件,但不会删除 ID 为“Comp1”的 ComponentRef。如何使用 XSLT 1.0 实现这一点?

4

2 回答 2

4

一种相当有效的方法是用来xsl:key识别配置组件的 ID:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="configComponent" 
      match="Component[File/@Source[substring(., 
               string-length() - string-length('config') + 1) = 'config']]" 
      use="@Id" />

    <xsl:template match="Component[key('configComponent', @Id)]" /> 

    <xsl:template match="ComponentRef[key('configComponent', @Id)]" /> 

    <xsl:template match="@*|node()"> 
        <xsl:copy> 
            <xsl:apply-templates select="@*|node()"/> 
        </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet>
于 2010-04-26T15:24:27.280 回答
0

这个怎么样?我对您的原始文件进行了一些小改动以简化事情(检查@source 属性是否以'config'结尾更简单)。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="Component[substring(@Source, string-length(@Source) - 5) = 'config']" />
    <xsl:template match="ComponentRef[//Component[substring(@Source, string-length(@Source) - 5) = 'config']/@Id = @Id]"/>
        <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

这有一个模板,该模板匹配任何 ComponentRef,该模板具有与前面模板匹配的 Component 相同的 Id 属性。一件事 - ' //Component' 效率不高。您应该能够用更有效的方法替换它 - 我不知道您的 XML 结构

于 2010-04-26T14:39:45.403 回答