【问题标题】:Unique ID and multiple classes with XPath具有 XPath 的唯一 ID 和多个类
【发布时间】:2011-01-04 03:33:12
【问题描述】:

我正在使用 XSLT 来显示包含 liaul 菜单。

我想要以下:

  1. 找到第一个 li a 元素并添加 .firstitem 类。
  2. 找到最后一个li a 元素并添加.lastitem 类。
  3. 找到活动的li a 元素并添加.active 类。
  4. 为每个li a 元素添加一个唯一的ID。 (即 URL 友好的菜单文本作为 ID)。

我已成功完成第 1-3 步。除了当我尝试添加类时,它实际上替换了其他类而不是添加到它们中。

代码如下:

<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 元素可以包含所有这三个类。但正如通过代码一样,它会替换 class 属性中的所有内容。如何添加类而不是替换它们?

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

菜单项文本包含在id 属性中无效的空格、破折号和其他符号。如何替换这些符号?

【问题讨论】:

    标签: xslt class xpath replace unique


    【解决方案1】:

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

    要使用 XSLT 1.0(您的第四个要求)从字符串中删除除特定范围的字符之外的所有内容,请执行以下操作。

    <!-- 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 中删除所有invalid 字符,无论它们在这种情况下可能是什么。仅保留有效字符。

    你可以用它做一个函数:

    <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】:

      使用

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

      复制所有现有属性。

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

      【讨论】:

      • 好的,我错过了这个问题只与类属性有关;我认为其他属性丢失了。
      【解决方案3】:
      <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() 是一个 XSLT2.0 函数。使用 XSLT1.0 时,您需要 custom template 来执行大多数字符串操作。

      【讨论】:

      • 我不敢相信我自己不知道这一点。当我现在看到它时是如此明显:P
      猜你喜欢
      • 1970-01-01
      • 2017-04-27
      • 1970-01-01
      • 2019-11-30
      • 1970-01-01
      • 2012-07-26
      • 2014-01-04
      • 2014-01-11
      • 1970-01-01
      相关资源
      最近更新 更多