除去使用XSLT 1.0相关元素(Removing related elements using X

2019-10-21 07:42发布

我试图删除下面的XML具有文件患儿扩展组件元素“配置”。 我已经成功地做到这一点的一部分,但我也需要删除具有相同的“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删除这些构成要素:

<?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”,而不是ComponentRef ID为“器Comp1”的组成部分。 如何做到这一点使用XSLT 1.0吗?

Answer 1:

一个相当有效的方法是使用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>


Answer 2:

这个怎么样? 我做了一个小的改变你原来把事情简单化,以及(这是简单的检查,如果@source属性与“配置”端)。

<?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>

这具有具有相同Id属性如由先前的模板相匹配的成分的任何ComponentRef匹配的模板。 一两件事- “ //Component ”效率不高。 你应该能够替换的东西更有效的 - 我不知道你的XML结构



文章来源: Removing related elements using XSLT 1.0