代码之家  ›  专栏  ›  技术社区  ›  chris85 Ferenc Kurucz

XSLT动态FO块创建

  •  0
  • chris85 Ferenc Kurucz  · 技术社区  · 8 年前

    我收到以下错误:

    XML解析器报告的错误:必须终止元素类型“fo:表行” 按匹配的结束标记“ </fo:table-row> “。

    尝试动态创建时 fo:table-row s

    这是我当前的XSLT代码:

    <xsl:template match="sec|ack">
        <xsl:call-template name="subtitle">
            <xsl:with-param name="text" select="title"/>
        </xsl:call-template>
            <fo:table width="100%">
                <fo:table-column column-width="45%"/>
                <fo:table-column column-width="45%"/>
                <fo:table-body>     
                    <xsl:for-each select="sec/*">
                        <xsl:variable name="i" select="position()" />
                        <xsl:if test="($i == 1)">
                            <fo:table-row>
                        </xsl:if>
                        <xsl:if test="($i mod 2) && $i > 1">
                            </fo:table-row>
                            <fo:table-row>
                        </xsl:if>
                        <fo:table-cell>
                            <fo:block><xsl:value-of select="*" /></fo:block>
                        </fo:table-cell>
                    </xsl:for-each>
                    </fo:table-row>
                </fo:table-body>
            </fo:table>
    </xsl:template>
    

    这就是我正在使用的XML(尽管我认为这是我的语法问题,而不是实际的XML):

    <sec>
        <title>Section Title</title>
        <sec>
            <title>Paragraph 1 Title</title>
            <p>Body paragraph</p>
        </sec>
        <sec>
            <title>Paragraph 2 Title</title>
            <list list-type="order">
                <list-item>
                    <p>Step 1.</p>
                </list-item>
                <list-item>
                    <p>Step 2.</p>
                </list-item>
                <list-item>
                    <p>Step 3.</p>
                </list-item>
                <list-item>
                    <p>Step 4.</p>
                </list-item>
                <list-item>
                    <p>Step 5.</p>
                </list-item>
                <list-item>
                    <p>Step 6.</p>
                </list-item>
                <list-item>
                    <p>Step  7.</p>
                </list-item>
                <list-item>
                    <p>Step 8.</p>
                </list-item>
                <list-item>
                    <p>Step 9.</p>
                </list-item>
                <list-item>
                    <p>Step 10.</p>
                </list-item>
                <list-item>
                    <p>Step 11.</p>
                </list-item>
                <list-item>
                    <p>Step 12.</p>
                </list-item>
                <list-item>
                    <p>Step 13.</p>
                </list-item>
                <list-item>
                    <p>Step 14.</p>
                </list-item>
            </list>
        </sec>
    </sec>
    

    我正在将历史代码从1列显示转换为2列显示。如果有更好的非表方法,我也会对此感兴趣。我试过使用 float 但无法使其正常工作。通过这种方法,我可以得到一个静态的2列显示工作。

    这是我的静态方法:

    <xsl:template match="sec|ack">
        <xsl:call-template name="subtitle">
            <xsl:with-param name="text" select="title"/>
        </xsl:call-template>
        <fo:table width="100%" >
            <fo:table-column column-width="45%"/>
            <fo:table-column column-width="45%"/>
            <fo:table-body>
                <fo:table-row>
                    <fo:table-cell>
                        <fo:block><xsl:apply-templates select="*[name()!='title']|text()" mode="xhtml"/></fo:block>
                    </fo:table-cell>
                    <fo:table-cell>
                        <fo:block>This is the second content block.</fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </fo:table-body>
        </fo:table>
    </xsl:template>
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Martin Honnen    8 年前

    正如您所指出的,您可以使用XSLT 2将位置分组用于 for-each-group group-adjacent="(position() - 1) idiv 2" 将每两个选定的相邻节点分组到表行中,而不是 <xsl:for-each select="sec/*"> 您使用

    <xsl:for-each-group select="*" group-adjacent="(position() - 1) idiv 2">
        <fo:table-row>
            <xsl:apply-templates select="current-group()" mode="cell"/>
        </fo:table-row>
    </xsl:for-each-group>
    

    然后编写一个模板,以该命名模式将任何元素转换为单元格:

    <xsl:template match="*" mode="cell">
        <fo:table-cell>
            <fo:block>
              <xsl:apply-templates/>
            </fo:block>
        </fo:table-cell>
    </xsl:template>