【问题标题】:XSLT - add attributes to result elements - xml to html transformtionXSLT - 向结果元素添加属性 - xml 到 html 的转换
【发布时间】:2015-09-15 11:45:21
【问题描述】:

我正在使用 xslt 进行 xml 到 html 的转换。我的输入xml如下,

<doc>
    <h1>main header 1-1</h1>
    <p>para 1</p>
    <p>para 2</p>

    <h1>main header 1-2</h1>
    <p>para 3</p>
    <p>para 4</p>
    <h2>sub header 2-1</h2>
    <p>para 5</p>
    <p>para 6</p>
    <p>para 7</p>
    <h2>sub header 2-3</h2>
    <p>para 8</p>
    <p>para 9</p>

    <h1>main header 1-3</h1>
    <p>para 10</p>
    <h2>sub header 2-3</h2>
    <p>para 11</p>
    <p>para 12</p>
</doc>

我需要使用上述 xml 数据创建菜单。我已经为菜单编写了 CSS。

我想要的上面xml的html输出代码如下,

<doc>
    <div name="list">
        <ul id="menu">
            <li class='has-sub'><a href="h1-1">main header 1-1</a></li>
            <li class='has-sub'><a href="h1-2">main header 1-2</a>
                <ul>
                    <li class='last'><a href="h2-1">sub header 2-1</a></li>
                    <li class='last'><a href="h2-2">sub header 2-2</a></li>
                </ul>
            </li>
            <li class='has-sub'><a href="h1-3">main header 1-3</a>
                <ul>
                    <li class='last'><a href="h2-3">sub header 2-3</a></li>
                </ul>
            </li>
        </ul>
    </div>
    <div class="main">

        <div id="h1-1">
            <h1>main header 1-1</h1>
            <p>para 1</p>
            <p>para 2</p>
        </div>

        <div id="h1-2">
            <h1>main header 1-2</h1>
            <p>para 3</p>
            <p>para 4</p>
            <div id="h2-1">
                <h2>sub header 2-1</h2>
                <p>para 5</p>
                <p>para 6</p>
                <p>para 7</p>
            </div>
            <div id="h2-2">
                <h2>sub header 2-3</h2>
                <p>para 8</p>
                <p>para 9</p>
            </div>
        </div>
        <div id="h1-3">
            <h1>main header 1-3</h1>
            <p>para 10</p>
            <div id="h2-3">
                <h2>sub header 2-3</h2>
                <p>para 11</p>
                <p>para 12</p>
            </div>
        </div>
    </div>
</doc>  

为了得到超出预期的结果,我的 xsl 代码如下,

<xsl:output indent="yes"/>

<xsl:function name="mf:group-list" as="element()*">
  <xsl:param name="elements" as="element()*"/>
  <xsl:param name="level" as="xs:integer"/>
  <xsl:if test="$elements[self::*[local-name() eq concat('h', $level)]]">
    <ul>
      <xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h', $level)]">
        <li>
          <a href="#{local-name()}-{count(preceding-sibling::*[local-name() eq local-name(current())]) + 1}">
            <xsl:value-of select="."/>
          </a>
          <xsl:sequence select="mf:group-list(current-group() except ., $level + 1)"/>
        </li>
      </xsl:for-each-group>
    </ul>
  </xsl:if>
</xsl:function>

<xsl:function name="mf:group-div" as="element()*">
  <xsl:param name="elements" as="element()*"/>
  <xsl:param name="level" as="xs:integer"/>
  <xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h', $level)]">
    <xsl:choose>
      <xsl:when test="self::*[local-name() eq concat('h', $level)]">
        <div id="{local-name()}-{count(preceding-sibling::*[local-name() eq local-name(current())]) + 1}">
          <xsl:copy-of select="."/>
          <xsl:sequence select="mf:group-div(current-group() except ., $level + 1)"/>
        </div>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="current-group()"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each-group>
</xsl:function>

<xsl:template match="doc">
  <xsl:copy>
    <div name="list">
      <xsl:sequence select="mf:group-list(h1 | h2 | h3 | h4 | h5 | h6, 1)"/>
    </div>
    <div class="main">
      <xsl:sequence select="mf:group-div(*, 1)"/>
    </div>
  </xsl:copy>
</xsl:template>

上面的 xslt 工作正常,它创建了我需要的无序列表,但是我不能将属性添加到列表项(css classid 以添加样式,如预期结果所示)。

我是 xslt 的新手,我尝试这样做但无法获得预期的结果。任何人都可以建议一种将这些属性添加到结果 html 的方法。

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    改变

      <xsl:if test="$elements[self::*[local-name() eq concat('h', $level)]]">
        <ul>
          ...
    

      <xsl:if test="$elements[self::*[local-name() eq concat('h', $level)]]">
        <ul>
          <xsl:if test="$elements[self::h1]">
            <xsl:attribute name="id">menu</xsl:attribute>
          </xsl:if>
          ...
    

    如果您想为所有li 元素添加class 属性,请更改

      <xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h', $level)]">
        <li>
    

      <xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h', $level)]">
        <li class="{if (self::h1) then 'has-sub' else 'last'}">
    

    【讨论】:

    • 感谢您的回答:)。第二部分工作正常,但是当将 id 属性添加到
        (第一部分)时,它给了我一个错误 - “评估总是会失败:没有上下文项”,知道为什么它不工作吗?
    猜你喜欢
    • 1970-01-01
    • 2010-10-13
    • 2011-02-13
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多