2014-09-24 59 views
0

製作一個表我有下面的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> 

這裏實際上我想將para轉換成表列,因爲我試過了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> 

請讓我知道我可以解決這個問題。

謝謝。

回答

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>