xslt动态启动和关闭标签

时间:2010-02-04 19:02:29

标签: xslt

我想做类似以下的事情:

<xsl:for-each select="Item">
  <xsl:if test="postion()=1 or position()=7>
    <ul>
  </xsl:if>
  <li>An Item</li>
  <xsl:if test="position()=2">
    </ul>
  </xsl>
</xsl:for-each>
</ul>

但这不起作用,因为xslt将if语句中未关闭的<ul>视为无效。

示例输入:

<Item>1</Item>
<Item>2</Item>

<Item>3</Item>

<Item>4</Item>

<Item>5</Item>

<Item>6</Item>

<Item>7</Item>

<Item>8</Item>

<Item>9</Item>

<Item>10</Item>

预期产出:

<ul>
<li>An Item<li>
<li>An Item<li>
<li>An Item<li>
<li>An Item<li>
<li>An Item<li>
<li>An Item<li>
</ul>
<ul>
<li>An Item<li>
<li>An Item<li>
<li>An Item<li>
<li>An Item<li>
</ul>

由于 -ben

2 个答案:

答案 0 :(得分:2)

你应该重写它以避免需要这种标签汤。首先对项目进行分组,以便在输出中将每个组转换为其自己的UL,然后迭代这些组(对于每个组,迭代其中的项目)。

对于您发布的特定代码,使用硬编码值,通过将Item的输出移动到其自己的模板(无论如何都是一个好主意),然后重复使用:

<xsl:template match="Item">
    <li>An Item</li>
</xsl:template>

...

<ul>
    <xsl:apply-templates select="Item[1]"/>
</ul>
<ul>
    <xsl:apply-templates select="Item[position() &ge; 2 and position() &le; 7]"/>
</ul>
<xsl:apply-templates select="Item[position() &gt; 7]"/>

但实际上,您可能有一些更复杂的方法来确定组的边界,但如果不知道确切的要求,在回答这个问题时很难更具体。如果您使用某个密钥,您可能希望查看Muenchian method分组。如果您的群组都是固定大小的,并且有一些硬编码的例外(例如,在其自己的群组中的第一个项目,然后每个接下来的10个项目组成一个新的群组),您可以代之以迭代位置。

答案 1 :(得分:2)

如果您想要的只是将项目分组为六个(或更少,最后)的组,那么您可以使用递归调用模板,该模板吐出列表中的前六个项目然后调用自己的任何一个遗留下来。

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:transform  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                version="1.0">
<xsl:output method="xml" indent="no" encoding="ISO-8859-1"/>

<xsl:template match="Item">
<li>Item</li>
</xsl:template>

<xsl:template name="group-of-six">
    <xsl:param name="items"/>

    <ul>
    <xsl:for-each select="$items[position() &lt; 7]">
    <xsl:apply-templates select="."/>
    </xsl:for-each>
    </ul>

    <xsl:if test="count($items) &gt; 6">
        <xsl:call-template name="group-of-six">
            <xsl:with-param name="items" select="$items[position() &gt; 6]"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template match="/">
    <Lists>
    <xsl:call-template name="group-of-six">
        <xsl:with-param name="items" select="//Item"/>
    </xsl:call-template>
    </Lists>
</xsl:template>

</xsl:transform>