简体   繁体   English

使用XSLT 1.0删除相关元素

[英]Removing related elements using XSLT 1.0

I'm attempting to remove Component elements from the XML below that have File children with the extension "config." 我正在尝试从下面的XML中删除具有File子节点且扩展名为“ config”的Component元素。 I've managed to do this part, but I also need to remove the matching ComponentRef elements that have the same "Id" values as these Components. 我已经设法完成了这一部分,但是我还需要删除与这些Components具有相同“ 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>

Based on other SO answers, I've come up with the following XSLT to remove these Component elements: 基于其他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>

Unfortunately, this doesn't remove the matching ComponentRef elements (ie those that have the same "Id" values). 不幸的是,这不会删除匹配的ComponentRef元素(即具有相同“ Id”值的元素)。 The XSLT will remove the component with the Id "Comp1" but not the ComponentRef with Id "Comp1". XSLT将删除ID为“ Comp1”的组件,但不会删除ID为“ Comp1”的ComponentRef。 How do I achieve this using XSLT 1.0? 如何使用XSLT 1.0做到这一点?

A fairly efficient approach is to use xsl:key to identify the IDs of config components: 一种相当有效的方法是使用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>

How about this? 这个怎么样? I've made a small change to your original to simplify things as well (it's simpler to check if the @source attribute ends with 'config'). 我还对您的原始文件做了一些小的更改以简化操作(检查@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>

This has a template that matches any ComponentRef that has the same Id attribute as a Component matched by the preceding template. 它具有一个模板,该模板与具有与上一个模板匹配的Component具有相同Id属性的ComponentRef匹配。 One thing - the ' //Component ' is not efficient. 一件事-' //Component '效率不高。 You should be able to replace that with something more efficient - I don't know your XML structure 您应该可以用效率更高的东西代替它-我不知道您的XML结构

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM