如何通过XSLT编码备用表行

时间:2012-03-13 18:54:08

标签: html xml xslt

我有结构:

<root>
    <relation type="relation1">
        <entityType1>a</entityType1>
        <entityType2>1</entityType2>
        <entityType2>2</entityType2>
        <entityType2>3</entityType2>
    </relation>

    <relation type="relation2">
        <entityType3>b</entityType3>
        <entityType4>7</entityType4>
        <entityType4>8</entityType4>
        <entityType4>9</entityType4>
    </relation>

    <relation type="relation3">
        <entityType5>c</entityType3>
        <entityType6>10</entityType4>
        <entityType6>11</entityType4>
        <entityType6>12</entityType4>
    </relation>
</root>

我需要通过XSLT转换为包含以下内容的HTML表:

<table>
    <tr class="odd"><td>
        a --> 1
    </td></tr>

    <tr><td>
        a --> 2
    </td></tr>

    <tr class="odd"><td>
        a --> 3
    </td></tr>

    <tr><td>
        b --> 7
    </td></tr>

    <tr class="odd"><td>
        b --> 8
    </td></tr>

    <tr><td>
        b --> 9
    </td></tr>

    <tr class="odd"><td>
        c --> 10
    </td></tr>

    <tr><td>
        c --> 11
    </td></tr>

    <tr class="odd"><td>
        c --> 12
    </td></tr>
</table>

请注意表行的奇/偶替换。我需要通过XSLT对它们进行编码。可能的?

基本问题实际上是如何在解析此结构时保留索引变量以指示当前行是奇数还是偶数。 这足以解决这个问题,因为我目前有一个...用于2种关系类型,然后我通过关系1 / entityType2上的for-each迭代,并且通过关系2 / entityType4转换为for-each。

谢谢!

UPDATE-1:

请注意,结果表遍历了relation1和relation2 XML元素,它必须以某种方式保持在两种关系类型之间运行的全局索引,以便在完成关系1迭代并传递给relation2时正确设置奇数/偶数类。

UPDATE-2:

目前我有一个类似于此的代码,但我不知道如何轻松地重构它来处理tr上的class =“odd”设置。模板Display_Relation当前显示关系的文本。

<xsl:template match="relation">
        <xsl:choose>
            <xsl:when test="contains(@xsi:type, 'relation1')">
                <xsl:for-each select="entityType2">
                    <tr><td>
                        <xsl:call-template name="Display_Relation1">
                            <xsl:with-param name="source" select="../entityType1/text()"/>
                            <xsl:with-param name="destination" select="./text()"/>
                        </xsl:call-template>
                    </td></tr>
                </xsl:for-each>
            </xsl:when>

            <xsl:when test="contains(@xsi:type, 'relation2')">
                <xsl:for-each select="entityType4">
                    <tr><td>
                        <xsl:call-template name="Display_Relation2">
                            <xsl:with-param name="source" select="../entityType3/text()"/>
                            <xsl:with-param name="destination" select="./text()"/>
                        </xsl:call-template>
                    </td></tr>
                </xsl:for-each>
            </xsl:when>

            <xsl:when test="contains(@xsi:type, 'relation3')">
                <xsl:for-each select="entityType6">
                    <tr><td>
                        <xsl:call-template name="Display_Relation3">
                            <xsl:with-param name="source" select="../entityType5/text()"/>
                            <xsl:with-param name="destination" select="./text()"/>
                        </xsl:call-template>
                    </td></tr>
                </xsl:for-each>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

2 个答案:

答案 0 :(得分:2)

尝试这样的事情......

<tr>
  <xsl:if test="boolean((count(preceding::*[parent::relation]) + 1) mod 2)">
    <xsl:attribute name="class">odd</xsl:attribute>
  </xsl:if>
  <xsl:apply-templates/>
</tr>

这假设当前上下文是*[parent::relation](entityType1,entityType2等),但关键部分是使用preceding::轴。

如果您愿意,还可以使用preceding::*[starts-with(name(),'entityType')]而非preceding::*[parent::relation]之类的内容。

答案 1 :(得分:1)

您可以轻松完成此操作。如果使用<relation>迭代第一个<xsl:for-each>的子元素,则可以使用position()函数获取行号,然后测试它是否有奇怪。

<xsl:for-each select="relation[@type='relation1']/*">
<tr>
<xsl:if test="position() mod 2 = 1">
  <xsl:attribute name="class">odd</xsl:attribute>

<!-- etc. -->

</tr>
</xsl:for-each>