扩展属性而不是设置它?

时间:2014-08-05 09:56:01

标签: xslt

我正在构建一个非常复杂的XSLT,以便生成一些HTML标记。

一方面,我的目标是"延伸"使用某些模板生成的标记的class属性。

不幸的是,它不起作用,因为XSLT标记<xsl:attribute>只能设置&#34;属性。不要操纵现有的。

当我尝试时,擦除原始属性。

这是一个小型的复制品:

XML:

<node>
    <item value="1" type="abc"/>
    <item value="20" type="zxy"/>
</node>

XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8" indent="no"/>
  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>
  <xsl:template match="/node/item">
    <p class="{@type}">
      <xsl:call-template name='rule1' />
      <xsl:call-template name='rule2' />
    </p>
  </xsl:template>
  <xsl:template name='rule1'>
    <xsl:attribute name='class'>
      <xsl:choose>
        <xsl:when test="@value mod 2 = 0">alpha</xsl:when>
        <xsl:otherwise>omega</xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
  </xsl:template>
  <xsl:template name='rule2'>
    <xsl:attribute name='class'>
      <xsl:choose>
        <xsl:when test="@value mod 10 = 0">beta</xsl:when>
        <xsl:otherwise>gamma</xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>                       

我想输出:

<?xml version="1.0" encoding="utf-8"?>
<p class="abc omega"/>
<p class="zxy beta alpha"/>

但它输出

<?xml version="1.0" encoding="utf-8"?>
<p class="omega"/>
<p class="beta"/>

是否可以保留原始属性,或在实用程序模板中检索它以重复使用它?

3 个答案:

答案 0 :(得分:1)

似乎这个答案只能满足一个深刻的,非重复的课程。 在您要调用的模板的开头包含此内容:

<xsl:variable name="type" select="@type"/>

然后在更新属性值时,请尝试:

<xsl:attribute select="class">
    <xsl:choose>
        <xsl:when test="@value mod 2 = 0">
            <xsl:value-of select="concat($type, ' alpha')"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="concat($type, ' omega')"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:attribute>

同样,我对XSLT并不是很满意,但我最近在测试中尝试了类似的东西,它起到了一定的作用。希望它有所帮助。

编辑:我不确定,但您可能必须将转义值放入&#34;空间&#34;在concat函数中,我忘了。

答案 1 :(得分:0)

一个接近的解决方案可能是(感谢@aleski建议)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8" indent="no"/>
  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>
  <xsl:template match="/node/item">
    <p>
    <xsl:attribute name='class'>
      <xsl:value-of select="@type" />
      <xsl:call-template name='rule1' />
      <xsl:call-template name='rule2' />
    </xsl:attribute>
    </p>
  </xsl:template>
  <xsl:template name='rule1'>
      <xsl:choose>
        <xsl:when test="@value mod 2 = 0"><xsl:value-of select="' alpha'" /></xsl:when>
        <xsl:otherwise><xsl:value-of select="' omega'" /></xsl:otherwise>
      </xsl:choose>
  </xsl:template>
  <xsl:template name='rule2'>

      <xsl:choose>
        <xsl:when test="@value mod 10 = 0"><xsl:value-of select="' beta'" /></xsl:when>
        <xsl:otherwise><xsl:value-of select="' gamma'" /></xsl:otherwise>
      </xsl:choose>

  </xsl:template>
</xsl:stylesheet>   

答案 2 :(得分:0)

你喜欢不起眼的编码解决方案吗?如果是这样,您可以重新编写解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8" indent="no"/>

  <xsl:template match="/node/item">
    <p class="{@type} {substring('alphaomega', 1 + 5 * (@value mod 2 = 0), 5)} {normalize-space(substring('beta gamma', 1 + 5 * (@value mod 10 = 0), 5))}">
    </p>
  </xsl:template>
</xsl:stylesheet>    

因此,在一个属性中有三个属性值模板。如果你看看其中一个......

{substring('alphaomega', 1 + 5 * (@value mod 10 = 0), 5)} 

这利用了&#34; true&#34;在数值表达式中求值为1,&#34; false&#34;求值为0.因此,当表达式为true时,将返回字符串的前五个字符。当它为假时,接下来的五个字符是。