在xsl-fo中将列表显示为表

时间:2014-12-08 15:36:14

标签: xslt xsl-fo

我试图将此列表呈现为xsl-fo

中的表格
<ul class="tablelist">
             <li class="a">A</li>
             <li class="a">A
    </li>
             <li class="b">B
    </li>
             <li class="b">B
    </li>
             <li class="a">A</li>
             <li class="b">B</li>
             <li class="a">A</li>
             </ul>

所有左栏中有A类的,右栏中有B类的。

我目前的解决方案:

  <fo:table>
              <fo:table-column column-number="1" column-width="30mm"/>
        <fo:table-column column-number="2" />
  <fo:table-body>
      <xsl:for-each select="li[@class='a']">
        <fo:table-row>
        <fo:table-cell column-number="1">
            <fo:block>
                <xsl:apply-templates/>
            </fo:block>
        </fo:table-cell>
        </fo:table-row>
      </xsl:for-each>
              <xsl:for-each select="li[@class='b']">
        <fo:table-row>
        <fo:table-cell column-number="2">
            <fo:block>
                <xsl:apply-templates/>
            </fo:block>
        </fo:table-cell>
        </fo:table-row>
      </xsl:for-each>
      </fo:table-body>
  </fo:table>

......当然没有用。我需要改变什么?

感谢您的帮助!

编辑:

在这种情况下,所需的输出将是:

<fo:table>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block>
A
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
B
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>
A
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
B
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>
A
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
B
</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>
A
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block/
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>

因为有四个类=&#34; a&#34;和三个等级=&#34; b&#34;元素。因此,总共4行,左边的单元格为4行,A为三行,右列为B.

希望,现在有点清楚了!

2 个答案:

答案 0 :(得分:2)

这是你可以看到它的另一种方式:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/">
    <table>
        <xsl:call-template name="generate-rows">
            <xsl:with-param name="left" select="ul/li[@class='a']"/>
            <xsl:with-param name="right" select="ul/li[@class='b']"/>
        </xsl:call-template>    
    </table>
</xsl:template>

<xsl:template name="generate-rows">
    <xsl:param name="left"/>
    <xsl:param name="right"/>
    <xsl:param name="i" select="1"/>
    <xsl:if test="$i &lt;= count($left) or $i &lt;= count($right)">
        <row>
            <cell><xsl:value-of select="$left[$i]"/></cell>
            <cell><xsl:value-of select="$right[$i]"/></cell>
        </row>
        <xsl:call-template name="generate-rows">
            <xsl:with-param name="left" select="$left"/>
            <xsl:with-param name="right" select="$right"/>      
            <xsl:with-param name="i" select="$i + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

一种选择是使用position()将模板应用于具有相同位置的相反类的元素。

如果你知道总是会有a个类元素而不是b类元素(或者如果你不关心剩下的b类元素会发生什么),那么你可以做这样的事情:

<xsl:template match="ul[@class='tablelist']">
    <fo:table>
        <fo:table-column column-number="1" column-width="30mm"/>
        <fo:table-column column-number="2" />
        <fo:table-body>
            <xsl:for-each select="li[@class='a']">
                <xsl:variable name="pos" select="position()"/>
                <fo:table-row>
                    <fo:table-cell column-number="1">
                        <fo:block>
                            <xsl:apply-templates/>
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell column-number="2">
                        <fo:block>
                            <xsl:apply-templates select="../li[@class='b'][position()=$pos]"/>
                        </fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </xsl:for-each>
        </fo:table-body>
    </fo:table>
</xsl:template>

如果你关心那些b类元素,当b多于a时,你可以这样做:

<xsl:template match="ul[@class='tablelist']">
    <fo:table>
        <fo:table-column column-number="1" column-width="30mm"/>
        <fo:table-column column-number="2" />
        <fo:table-body>
            <xsl:choose>
                <xsl:when test="count(li[@class='a']) >= count(li[@class='a'])">
                    <xsl:apply-templates select="li[@class='a']" mode="createRow"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="li[@class='b']" mode="createRow"/>                        
                </xsl:otherwise>
            </xsl:choose>
        </fo:table-body>
    </fo:table>
</xsl:template>

<xsl:template match="li[@class='a']" mode="createRow">
    <xsl:variable name="pos" select="position()"/>
    <fo:table-row>
        <fo:table-cell column-number="1">
            <fo:block>
                <xsl:apply-templates/>
            </fo:block>
        </fo:table-cell>
        <fo:table-cell column-number="2">
            <fo:block>
                <xsl:apply-templates select="../li[@class='b'][position()=$pos]"/>
            </fo:block>
        </fo:table-cell>
    </fo:table-row>
</xsl:template>

<xsl:template match="li[@class='b']" mode="createRow">
    <xsl:variable name="pos" select="position()"/>
    <fo:table-row>
        <fo:table-cell column-number="1">
            <fo:block>
                <xsl:apply-templates select="../li[@class='a'][position()=$pos]"/>
            </fo:block>
        </fo:table-cell>
        <fo:table-cell column-number="2">
            <fo:block>
                <xsl:apply-templates/>
            </fo:block>
        </fo:table-cell>
    </fo:table-row>
</xsl:template>