使用XSLT更改单个属性

7
你能想到的最简单的XSLT转换是什么?它可以将第一个(在这种情况下是唯一的)/configuration/system.web/compilation/@debug属性的值从true转换为false

好问题(+1)。看看我的答案,它提供了一个简短、简单和正确的解决方案。Lucero目前的答案是相当不正确的--请看看我对他回答的评论。 - Dimitre Novatchev
2个回答

6

这个转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="system.web/compilation[1]/@debug">
  <xsl:attribute name="debug">false</xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

当应用于此XML文档时:

<configuration>
    <system.web>
        <compilation debug="true" defaultLanguage="C#">
            <!-- this is a comment -->
        </compilation>

        <compilation debug="true" defaultLanguage="C#">
            <!-- this is another comment -->
        </compilation>
    </system.web>
</configuration>

产生所需的正确结果:修改任何system.web元素的第一个compilation子元素的debug属性(但我们知道配置文件中只有一个system.web元素)。

<configuration>
    <system.web>
        <compilation debug="false" defaultLanguage="C#">
            <!-- this is a comment -->
        </compilation>
        <compilation debug="true" defaultLanguage="C#">
            <!-- this is another comment -->
        </compilation>
    </system.web>
</configuration>

正如我们所看到的,只有第一个debug属性被修改为false,符合要求。


1
这被称为XSLT的身份模式转换,正如@Dimitre Novatchev指出的那样,它非常强大。 - lavinio
很遗憾,xsl:attribute 元素必须提及要更改的属性名称,而这已经在封闭的 xsl:template 匹配的 XPath 中给出。有没有办法说“设置此属性,无论它叫什么”? - Tom Anderson
@TomAnderson:可以使用AVT符号表示法:<someElement attr1="{someExpression}"/>。这不是你想要的,但在某些方面甚至更好。 - Dimitre Novatchev
您的意思是与具有该属性的元素匹配结合使用吗?那么您将面临更糟糕的问题(我认为),即需要手动复制所有不想保留的属性。 - Tom Anderson
@TomAnderson:但你“完全掌控”。所以,再谈谈你最初的问题:不,这是一个太复杂的操作,如果该语言具有表示所有可能复合操作的单个指令,它将会非常庞大且难以使用。 - Dimitre Novatchev

-1

<compilation>内部使用<xsl:attribute name="debug">false</xsl:attribute>吗?还是我误解了问题?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接