使用XSLT将模板内容分为三个

时间:2012-09-03 13:00:27

标签: xslt

我想在我的xslt代码中动态地将表分成三个。 给我结构将我的文本附加到特定节点,就好像我有100个节点,我需要在第33个第66节点附加我的文本。

我的XSLT代码:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

<xsl:key name="routes-by-origin" match="/schedules/Routes/org" use="./text()"/>
<xsl:template match="schedules" name="Main">
<html>
<head></head>
<body>
<table>
<tr> <td> Heading </td> </tr>
<table>
<xsl:for-each select="Routes/org[generate-id(.) = generate-id(key('routes-by-origin',.)[1])]">
   <xsl:value-of select="./text()"/>
  <xsl:apply-templates select="//Routes[org/text() = current()/text()]"/>
     </xsl:for-each>
    </table>
   </xsl:template>

从上面的模板调用模板设计

   <xsl:template match="Routes">
  <xsl:value-of select="des/text()"/>
<xsl:variable name="via" select="Via/text()"/>
 <xsl:value-of select="Flgno/text()"/>
</xsl:template>
 </xsl:stylesheet>

输入文件

<schedules>
    <Routes>
        <org>Agartala</org>
        <des>Bangalore</des>
        <Flgno>SG 872</Flgno>
        <Via>CCU, HYD</Via>
    </Routes>
    <Routes>
        <org>Agartala</org>
        <des>Guwahati</des>
        <Flgno>SG 873</Flgno>
        <Via> BOM </Via>
    </Routes>
    <Routes>
        <org>Agartala</org>
        <des>Hyderabad</des>
        <Flgno>SG 872</Flgno>
        <Via>CCU</Via>
    </Routes>
    <Routes>
        <org>Agartala</org>
        <des>Kolkata</des>
        <Flgno>SG 872</Flgno>
        <Via> - </Via>
    </Routes>
    <Routes>
        <org>Agartala</org>
        <des>Kolkata</des>
        <Flgno>SG 874</Flgno>
        <Via> - </Via>
    </Routes>
    <Routes>
        <org>Agartala</org>
        <des>Mumbai</des>
        <Flgno>SG 874</Flgno>
        <Via>CCU</Via>
    </Routes>
    <Routes>
        <org>Ahmedabad</org>
        <des>Bangalore</des>
        <Flgno>SG 528</Flgno>
        <Symbols> - </Symbols>
        <Via>BOM</Via>
    </Routes>
</schedules>

预期结果

我的输出应该在一个页面中的三个表中: 在第一个表中 前2条记录 第二个表 - 接下来的2个记录 第三张表最后3条记录

2条记录 2条记录 3条记录
<table>
    <table>
        <tr>
            <td>Agartala</td>
            <td>Bangalore</td>
            <td>SG 872</td>
            <td>CCU</td>
        </tr>
        <tr>
            <td> Agartala</td>
            <td>Guwahati</td>
            <td>SG 87</td>
            <td>BOM</td>
        </tr>
    </table>
    <table>
        <tr>
            <td>Agartala</td>
            <td>Hyderabad</td>
            <td>SG 872 </td>
            <td>CCU</td>
        </tr>
        <tr>
            <td>Agartala</td>
            <td>Kolkatta</td>
            <td>SG 872</td>
            <td> - </td>
        </tr>
    </table>
    <table>
        <tr>
            <td> Agartala</td>
            <td>Kolkatta</td>
            <td>SG 874</td>
            <td> - </td>
        </tr>
        <tr>
            <td>Agartala</td>
            <td>Mumbai</td>
            <td>SG 874 </td>
            <td>CCU</td>
        </tr>
        <tr>
            <td>Agartala</td>
            <td>Bangalore</td>
            <td>SG 528</td>
            <td>BOM</td>
        </tr>
    </table>
</table>

注意:我的输入数据是动态的

1 个答案:

答案 0 :(得分:0)

这个XSLT 1.0样式表是Dimitre解决方案here的副本,稍微调整了OP的特定数据,并使第3个表具有ceil(行数/ 3)行。

XSLT 1.0解决方案

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

<xsl:variable name="prowLimit" select="floor(count(/*/Routes) div 3)" />

<xsl:template match="/">
 <table>
   <xsl:apply-templates select="*/Routes" />
 </table>
</xsl:template>

<xsl:template match="Routes">
 <xsl:if test="(position() mod $prowLimit = 1) and 
               (position() &lt; (3 * $prowLimit + 1))"> 
  <xsl:variable name="is-last-table" select="position() - (2*$prowLimit)" />               
  <table>
    <xsl:for-each select=".|following-sibling::Routes[
      not(position() > $prowLimit - 1) or ($is-last-table > 0)]" >
      <tr>
        <td><xsl:value-of select="org" /></td> 
       <td><xsl:value-of select="des" /></td> 
       <td><xsl:value-of select="Flgno" /></td> 
       <td><xsl:value-of select="Via" /></td>
      </tr>
    </xsl:for-each>  
  </table>
 </xsl:if> 
</xsl:template>

</xsl:stylesheet>

XSLT 2.0解决方案

在XSLT 2.0中变得更容易......

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  exclude-result-prefixes="xsl fn">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
 <xsl:variable name="prowLimit" select="floor(count(/*/Routes) div 3)" /> 
 <table>
   <xsl:for-each-group select="*/Routes"
       group-adjacent="fn:min((floor((position() - 1) div $prowLimit),2))" >
     <table>
       <xsl:apply-templates select="current-group()" />
     </table>
   </xsl:for-each-group>
 </table>
</xsl:template>

<xsl:template match="Routes">
      <tr>
       <td><xsl:value-of select="org" /></td> 
       <td><xsl:value-of select="des" /></td> 
       <td><xsl:value-of select="Flgno" /></td> 
       <td><xsl:value-of select="Via" /></td>
      </tr>
</xsl:template>

</xsl:stylesheet>