【问题标题】:making a table from paragraphs从段落制作表格
【发布时间】:2014-09-24 13:55:23
【问题描述】:

我有以下 XML。

<?xml version="1.0" encoding="UTF-8"?>
<root>
<para align="center">BETWEEN</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="2">Column2 data</para>
<para columns="3">Column3 data</para>
<para align="center">AND</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="2">Column2 data</para>
<para columns="3">Column3 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para align="center">Between</para>
<para align="center">____________________</para>
</root>

这里实际上我想将 paras 转换为表格列,因为我已经尝试过 XSLT。但这里的问题是,每个段落都会创建一个新表。

这里columns属性说明数据属于哪一列,如果columns="1"表示只有一行一列。如果是columns="2",则表示数据与第2列的内容属于同一行,如果前面有columns="1",则同一行的第1列应该有内容,否则第1列应该留空.

我试过的代码可以在here找到

预期的输出是

    <table>
        <tr>
            <td>Column1 data</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Column1 data</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Column1 data</td>
            <td>Column 2 data</td>
            <td>Column 3 data</td>
        </tr>
    </table>
    <div class="para align-center">AND</div>
   <table>
        <tr>
            <td>Column1 data</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Column1 data</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Column1 data</td>
            <td>Column 2 data</td>
            <td>Column 3 data</td>
        </tr>
    </table>
   <table>
        <tr>
            <td>Column1 data</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Column1 data</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>Column1 data</td>
            <td>Column 2 data</td>
            <td>Column 3 data</td>
        </tr>
    </table>

   <table>
        <tr>
            <td></td>
            <td>Column2 data</td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>Column 2 data</td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>Column 2 data</td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>Column2 data</td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>Column 2 data</td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td>Column 2 data</td>
            <td></td>
        </tr>
    </table>
    <div class="para align-center">BETWEEN</div>

请告诉我如何解决这个问题。

谢谢。

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    如果您真正使用 XSLT 2.0(链接示例中的处理器是 2.0 处理器,但您的 XSLT @version 是 1.0)您应该能够使用 xsl:for-each-group。您可以将para 元素分组到表格中,然后将它们分组到这些表格中的行中。

    可能有更好的方法来做到这一点,但我只有几分钟的时间来尝试一下。希望这足以让您入门。

    XML 输入(稍作修改以进行测试)

    <root>
        <para align="center">BETWEEN</para>
        <para columns="1">Column1 data</para>
        <para columns="1">Column1 data</para>
        <para columns="1">Column1 data</para>
        <para columns="2">Column2 data</para>
        <para columns="3">Column3 data</para>
        <para align="center">AND</para>
        <para columns="1">Column1 data</para>
        <para columns="1">Column1 data</para>
        <para columns="1">Column1 data</para>
        <para columns="2">Column2 data</para>
        <para columns="3">Column3 data</para>
        <para columns="2">Column2 data</para>
        <para columns="2">Column2 data</para>
        <para columns="2">Column2 data</para>
        <para columns="2">Column2 data</para>
        <para columns="2">Column2 data</para>
        <para columns="2">Column2 data</para>
        <!--Added for testing-->
        <para columns="1">Column1 data</para>
        <para columns="3">Column3 data</para>
        <!--=================-->
        <para align="center">Between</para>
        <para align="center">____________________</para>
    </root>
    

    XSLT 2.0

    <xsl:stylesheet version="2.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="xs">
        <xsl:output indent="yes" method="html"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:variable name="max-cols" select="max(/*/para/@columns)"/>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="/*">
            <xsl:for-each-group select="para" group-ending-with="para[@columns][@columns > following-sibling::para[@columns][1]/@columns]">
                <xsl:apply-templates select="current-group()[not(@columns)][following-sibling::para[generate-id()=generate-id((current-group()[@columns])[1])]]"/>
                <table>
                    <xsl:for-each-group select="current-group()[@columns]" group-starting-with="para[preceding-sibling::para[1]/@columns >= @columns]">
                        <tr>
                            <xsl:call-template name="empty-cols">
                                <xsl:with-param name="col-cnt" select="xs:integer(current-group()[position()=1]/@columns - 1)"/>
                            </xsl:call-template>
                            <xsl:apply-templates select="current-group()"/>
                            <xsl:call-template name="empty-cols">
                                <xsl:with-param name="col-cnt" select="xs:integer($max-cols - current-group()[last()]/@columns)"/>
                            </xsl:call-template>
                        </tr>                        
                    </xsl:for-each-group>
                </table>
                <xsl:apply-templates select="current-group()[not(@columns)][preceding-sibling::para[generate-id()=generate-id((current-group()[@columns])[last()])]]"/>                        
            </xsl:for-each-group>
        </xsl:template>
    
        <xsl:template name="empty-cols">
            <xsl:param name="col-cnt" as="xs:integer"/>
            <xsl:for-each select="1 to $col-cnt">
                <td/>
            </xsl:for-each>
        </xsl:template>
    
        <xsl:template match="para[not(@columns)]">
            <div class="para{if (string(@align)) then concat(' align-',@align) else ''}">
                <xsl:apply-templates/>
            </div>
        </xsl:template>
    
        <xsl:template match="para[@columns]">
            <xsl:call-template name="empty-cols">
                <xsl:with-param name="col-cnt" select="if (preceding-sibling::para[1][@columns][current()/@columns >= @columns - 1]) then xs:integer((@columns - 1) - preceding-sibling::para[1][@columns]/@columns) else xs:integer(0)"/>
            </xsl:call-template>        
            <td>
                <xsl:apply-templates/>
            </td>
        </xsl:template>
    
    </xsl:stylesheet>
    

    输出

    <div class="para align-center">BETWEEN</div>
    <table>
       <tr>
          <td>Column1 data</td>
          <td></td>
          <td></td>
       </tr>
       <tr>
          <td>Column1 data</td>
          <td></td>
          <td></td>
       </tr>
       <tr>
          <td>Column1 data</td>
          <td>Column2 data</td>
          <td>Column3 data</td>
       </tr>
    </table>
    <div class="para align-center">AND</div>
    <table>
       <tr>
          <td>Column1 data</td>
          <td></td>
          <td></td>
       </tr>
       <tr>
          <td>Column1 data</td>
          <td></td>
          <td></td>
       </tr>
       <tr>
          <td>Column1 data</td>
          <td>Column2 data</td>
          <td>Column3 data</td>
       </tr>
    </table>
    <table>
       <tr>
          <td></td>
          <td>Column2 data</td>
          <td></td>
       </tr>
       <tr>
          <td></td>
          <td>Column2 data</td>
          <td></td>
       </tr>
       <tr>
          <td></td>
          <td>Column2 data</td>
          <td></td>
       </tr>
       <tr>
          <td></td>
          <td>Column2 data</td>
          <td></td>
       </tr>
       <tr>
          <td></td>
          <td>Column2 data</td>
          <td></td>
       </tr>
       <tr>
          <td></td>
          <td>Column2 data</td>
          <td></td>
       </tr>
    </table>
    <table>
       <tr>
          <td>Column1 data</td>
          <td></td>
          <td>Column3 data</td>
       </tr>
    </table>
    <div class="para align-center">Between</div>
    <div class="para align-center">____________________</div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-28
      • 2018-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多