XSLT将pargraph分成两列表

时间:2016-02-17 16:40:40

标签: xslt

我有一个未知数量的段落,我想格式化为两列表。所以,如果我有一个偶数段落,我想从

开始
<doc>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
<p>Paragraph 4</p>
</doc>

<table>
  <row>
    <entry>
      <p>Paragraph 1</p>
      <p>Paragraph 2</p>
    </entry>
    <entry>
      <p>Paragraph 3</p>
      <p>Paragraph 4</p>
    </entry>
  </row>
</table>

如果我有一个奇数段落,我想在第一栏中再分开一段(7段= 4 / 3,11段= 6/5等)。

我无法弄清楚如何迭代段落并将它们放在正确的列中。我需要开始/结束表格,无论如何,唯一真正的挑战是决定何时结束第1列并开始第2列。我想我需要在开始之前存储段落数量,然后在我到达时移动到第2列正确的段落编号,但我在这方面遇到了麻烦。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

首先,您可以计算第一个条目中所需的p元素数量:

 <xsl:variable name="count" select="ceiling(count(p) div 2)" />

然后,您可以选择位置1中出现的p元素和count + 1的位置,因为它们代表每个entry中的第一个元素

<xsl:for-each select="p[position() = 1 or position() = $count + 1]">

然后您可以为每个条目选择p标签,如下所示:

<xsl:apply-templates select="self::p|following::p[position() &lt; $count]" />

试试这个XSLT

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

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="doc">
        <table>
          <row>
            <xsl:variable name="count" select="ceiling(count(p) div 2)" />
            <xsl:value-of select="$count" />
            <xsl:for-each select="p[position() = 1 or position() = $count + 1]">
                <entry>
                  <xsl:apply-templates select="self::p|following::p[position() &lt; $count]" />
                </entry>
            </xsl:for-each>
          </row>
        </table>
    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

实现此目标的一种可能性是以下XSLT代码段。它将position() < ((last() of element p)/2+1)的计数与不在该节点集中的计数分开。其余部分只需复制,并在doc模板中创建周围的元素(确认最佳实践)。

<xsl:template match="/doc">
    <xsl:element name="table">
        <xsl:element name="row">
            <xsl:element name="entry">
                <xsl:apply-templates select="p[position() &lt; (last() div 2)+1]" />
            </xsl:element>
            <xsl:element name="entry">
                <xsl:apply-templates select="p[not(position() &lt; (last() div 2)+1)]" />
            </xsl:element>
        </xsl:element>
    </xsl:element>
</xsl:template>

<xsl:template match="p">
    <xsl:copy-of select="." />
</xsl:template>