如何使用XSLT修改XML属性?

时间:2012-12-30 19:36:03

标签: xml xslt

我想知道在XSLT中是否有办法修改/添加属性值。

现在我只是替换属性值:

<a class="project" href="#">
  <xsl:if test="new = 'Yes'">
    <xsl:attribute name="class">project new</xsl:attribute>
  </xsl:if>
</a>

但我不喜欢第2行中project的重复。有没有更好的方法来做到这一点,例如只需在属性的末尾添加 new

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

您可以将if放在attribute内,而不是相反:

<a href="#">
  <xsl:attribute name="class">
    <xsl:text>project</xsl:text>
    <xsl:if test="new = 'Yes'">
      <xsl:text> new</xsl:text>
    </xsl:if>
  </xsl:attribute>
</a>

<xsl:attribute>可以包含任何有效的XSLT模板(包括for-each循环,应用其他模板等),唯一的限制是实例化此模板必须只生成文本节点,而不是元素,属性等。属性值将是所有这些文本节点的串联。

答案 1 :(得分:0)

在XSLT 1.0中,可以使用此单行

<a class="project{substring(' new', 5 - 4*(new = 'Yes'))}"/>

这是一个完整的转型

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

 <xsl:template match="/*">
  <a class="project{substring(' new', 5 - 4*(new = 'Yes'))}"/>
 </xsl:template>
</xsl:stylesheet>

对以下XML文档应用此转换时:

<t>
 <new>Yes</new>
</t>

产生了想要的正确结果:

<a class="project new"/>

<强>解释

  1. 使用 AVT (属性值模板)

  2. 要根据条件选择字符串,在XPath 1.0中,可以使用子字符串函数并指定一个表达式作为起始索引参数,当条件为true()时,该表达式的计算结果为1数字大于字符串的长度 - otherwize。

  3. 我们使用这样的事实:在XPath 1.0中*(乘法)运算符的任何参数都转换为数字,而number(true()) = 1number(false()) = 0


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

    使用此单行

      <a class="project{(' new', '')[current()/new = 'Yes']}"/>
    

    这是一个完整的转型

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="/*">
      <a class="project{(' new', '')[current()/new = 'Yes']}"/>
     </xsl:template>
    </xsl:stylesheet>
    

    当应用于同一个XML文档(上图)时,再次生成相同的想要的正确结果:

    <a class="project new"/>
    

    <强>解释

    1. 正确使用 AVT

    2. 正确使用 sequences

    3. 正确使用XSLT current() 功能。