如何使用XSLT删除属性值与给定值不同的节点?

时间:2013-03-08 02:53:56

标签: .net xml xslt xpath web-config

在给定的非常简单和标准的配置中:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:env="urn:schemas-test-env">
    <appSettings>
        <add key="Name" value="Value" />
        <add key="Name" value="Value" env:name="Dev" />
        <add key="Name" value="Value" env:name="QA" />
    </appSettings>

    <!-- rest of the config -->

</configuration>

我想使用XSLT删除<add />所有节点@env:name != $env?我的主要问题是保留配置的其余部分。

到目前为止我所拥有的:

<!-- populated by inline C# code -->
<xsl:variable name="env" select="code:GetEnvironment()" />

<!-- Leave as is -->
<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
</xsl:template>

<!-- Remove non-matching nodes -->
<xsl:template match="configuration/appSettings/add">
    ???
</xsl:template>

我还有一个存根:

<xsl:choose>
    <xsl:when test="not(@env:name)">
        <xsl:value-of select="'no env'" />
    </xsl:when>
    <xsl:when test="./@env:name = $env">
        <xsl:value-of select="'Env eq var'" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="'Env neq var'" />
    </xsl:otherwise>
</xsl:choose>

1 个答案:

答案 0 :(得分:2)

此转化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:env="urn:schemas-test-env">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:param name="env" select="'QA'"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="add">
  <xsl:if test="not(@env:name = $env)">
   <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<configuration xmlns:env="urn:schemas-test-env">
    <appSettings>
        <add key="Name" value="Value" />
        <add key="Name" value="Value" env:name="Dev" />
        <add key="Name" value="Value" env:name="QA" />
    </appSettings>
    <!-- rest of the config -->
</configuration>

会产生想要的正确结果:

<configuration xmlns:env="urn:schemas-test-env">
   <appSettings>
      <add key="Name" value="Value"/>
      <add key="Name" value="Value" env:name="Dev"/>
   </appSettings><!-- rest of the config -->
</configuration>

<强>解释

正确使用和覆盖 identity rule


<强> II。 XSLT 2.0+解决方案:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:env="urn:schemas-test-env">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:param name="env" select="'QA'"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="add[@env:name = $env]"/>
</xsl:stylesheet>

<强>解释

XSLT 2.0与XSLT 1.0的不同之处在于它允许变量引用作为匹配模式谓词的一部分。此功能可以只使用一个空的覆盖模板。