具有XPath的唯一ID和多个类

时间:2010-01-12 11:34:36

标签: xslt class xpath replace unique

我正在使用 XSLT 来显示包含ulli的{​​{1}}菜单。

我想要以下内容:

  1. 找到第一个a元素并添加li a类。
  2. 找到最后一个.firstitem元素并添加li a类。
  3. 找到有效的.lastitem元素并添加li a类。
  4. 为每个.active元素添加唯一ID。 (即,URL友好菜单文本为ID)。
  5. 我设法让步骤1-3工作。除了当我尝试添加类时,它实际上替换了其他类而不是添加它们。

    以下是代码:

    li a

    实际上,<li> <a> <!-- Add .firstitem class --> <xsl:if test="position() = 1"> <xsl:attribute name="class">firstitem</xsl:attribute> </xsl:if> <!-- Add .lastitem class --> <xsl:if test="postition() = count(//Page)"> <xsl:attribute name="class">lastitem</xsl:attribute> </xsl:if> <!-- Add .active class --> <xsl:if test="@Active='True'"> <xsl:attribute name="class">active</xsl:attribute> </xsl:if> <!-- Add link URL --> <xsl:attribute name="href"><xsl:value-of select="@FriendlyHref" disable-output-escaping="yes"/></xsl:attribute> <!-- Add link text --> <xsl:value-of select="@MenuText" disable-output-escaping="yes"/> </a> </li> 元素可以包含所有这三个类。但是通过代码,它会替换a属性中的所有内容。如何添加类而不是替换它们?

    我的列表中的第4步是获取唯一ID,最好是基于class。我知道有一个@MenuText函数,但我无法让它工作,我的编辑说replace()不是函数。

    菜单项文本包含空格,短划线和其他符号,这些符号在replace()属性中无效。我该如何更换这些符号?

3 个答案:

答案 0 :(得分:6)

<a>
       <xsl:attribute name="class">
            <!-- Add .firstitem class -->
            <xsl:if test="position() = 1">
                <xsl:text> firstitem</xsl:text>
            </xsl:if>
            <!-- Add .lastitem class -->
            <xsl:if test="postition() = count(//Page)">
                <xsl:text> lastitem</xsl:text>
            </xsl:if>

            <!-- Add .active class -->
            <xsl:if test="@Active='True'">
                <xsl:text> active</xsl:text>
           </xsl:if>
       </xsl:attribute>

        <!-- Add link URL -->
        <xsl:attribute name="href"><xsl:value-of select="@FriendlyHref" disable-output-escaping="yes"/></xsl:attribute>

        <!-- Add link text -->
        <xsl:value-of select="@MenuText" disable-output-escaping="yes"/>
    </a>

replace()是一个XSLT 2.0函数。使用XSLT 1.0时,需要custom template来执行大多数字符串操作。

答案 1 :(得分:4)

我将此添加到Martijn Laarman的答案中,该答案涵盖了您的要求1-3并且得到了我的投票:

要从XSLT 1.0(第4项要求)的字符串中删除除特定范围字符以外的所有字符,请执行以下操作。

<!-- declare at top level -->
<xsl:variable 
  name="validRange" 
  select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' 
/>

<!-- later, within a template… -->
<xsl:attribute name="id">
  <xsl:value-of select="
    concat(
      'id_',
      translate(
        @MenuText, 
        translate(@MenuText, $validRange, ''),
        ''
      )
    )
  " />
</xsl:attribute>

内部translate()删除@MenuText中的所有有效字符,只留下无效字符。它们被馈送到外部translate(),现在可以从@MenuText删除所有无效字符,无论它们在此实例中是什么。只剩下有效的字符。

你可以用它来制作一个功能:

<xsl:template name="HtmlIdFromString">
  <xsl:param name="input" select="''" />
  <xsl:value-of select="
    concat('id_', translate( $input, translate($input, $validRange, ''), ''))
  " />
</xsl:template>

并将其称为:

<xsl:attribute name="id">
  <xsl:call-template name="HtmlIdFromString">
    <xsl:with-param name="input" select="@MenuText" />
  </xsl:call-template>
</xsl:attribute>

答案 2 :(得分:0)

<击>使用

<击>
<xsl:template match="@*">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
    </xsl:copy>
</xsl:template>

复制所有现有属性。

仅在xslt 2.0中支持replace()函数,但我发现xslt 1.0为this workaround