Xslt垂直索引两列(50行)

时间:2014-12-02 12:10:05

标签: xslt xslt-1.0

我想用两列垂直创建一个索引,每列有50行。

我使用这个XSLT创建了一个简单的垂直索引(在一列中):

<span style="font-family:Univers Condensed; font-size:9pt; ">   
    <xsl:for-each select="//VICINITY[not(. = preceding::VICINITY)]">            
        <xsl:sort select="." data-type="text" order="ascending"/>
        <xsl:sort select="preceding-sibling::ITA_LIGHT_NUMBER" data-type="text" order="ascending"/>
        <xsl:variable name ="localita" select="."/>
        <xsl:value-of select="."/>
        <xsl:text>....................</xsl:text>
        <xsl:value-of select="preceding-sibling::ITA_LIGHT_NUMBER"/>
            <xsl:for-each select="following::VICINITY[. = $localita][last()]">
                <xsl:text> - </xsl:text>
                <xsl:value-of select="preceding-sibling::ITA_LIGHT_NUMBER"/>
            </xsl:for-each>
            <br/>           
    </xsl:for-each>
</span>

这是我的输出:

ACCIAROLI ........... 2665.3 - 2666.5
阿门多拉拉.......... 3431.25
ANCONA .............. 3921.9
BRINDISI ............ 3624
CASTELLAMMARE ....... 2573.5
基奥贾............ 4108
CORIGLIANO CALABRO..3429.2 - 3429.55
FIUME TRIONTO ....... 3427
FRIGOLE ............. 3614.3
GENOVA .............. 1577

但是我会将表中的垂直索引分为两列:(对于此示例,我将表格减少为五行)

<table>
    <tr>
    <td>ACCIAROLI.....2665.3 - 2666.5</td>      <td>CHIOGGIA............4108<br/></td>
    </tr>
    <tr>    
    <td>AMENDOLARA......3431.25</td>            <td>CORIGLIANO....3429.2-3429.55<br/></td>
    </tr>
    <tr>
    <td>ANCONA............3921.9</td>           <td>FIUME TRIONTO.......3427<br/></td>
    </tr>
    <tr>
    <td>BRINDISI...........3624</td>            <td>FRIGOLE.............3614.3<br/></td>
    </tr>
    <tr>
    <td>CASTELLAMMARE.....2573.5</td>           <td>GENOVA..............1577<br/></td>
    </tr>
</table>

这是我的XML:

<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>              
        <ITA_LIGHT_NUMBER>2665.3</ITA_LIGHT_NUMBER>              
        <VICINITY>ACCIAROLI</VICINITY>
        <ITA_LIGHT_NAME>Secca Vecchia</ITA_LIGHT_NAME>              
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>              
        <ITA_LIGHT_NUMBER>2666.5</ITA_LIGHT_NUMBER>
        <VICINITY>ACCIAROLI</VICINITY>
        <ITA_LIGHT_NAME>Ondametro</ITA_LIGHT_NAME>              
        </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>              
        <ITA_LIGHT_NUMBER>3431.25</ITA_LIGHT_NUMBER>
        <VICINITY>AMENDOLARA</VICINITY>
        <ITA_LIGHT_NAME>Impianto di itticoltura;Boa "A"</ITA_LIGHT_NAME>
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>              
        <ITA_LIGHT_NUMBER>3921.9</ITA_LIGHT_NUMBER>              
        <VICINITY>ANCONA</VICINITY>
        <ITA_LIGHT_NAME>Installazioni per idrocarburi;BARBARA H</ITA_LIGHT_NAME>              
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>              
        <ITA_LIGHT_NUMBER>3624</ITA_LIGHT_NUMBER>              
        <VICINITY>BRINDISI</VICINITY>
        <ITA_LIGHT_NAME>Brindisi-Casale (AERO)</ITA_LIGHT_NAME>
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>          
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>              
        <ITA_LIGHT_NUMBER>2573.5</ITA_LIGHT_NUMBER>
        <VICINITY>CASTELLAMMARE DI STABIA</VICINITY>
        <ITA_LIGHT_NAME>Impianti di mitilicoltura;Boa SW</ITA_LIGHT_NAME>              
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>
        <ITA_LIGHT_NUMBER>4108</ITA_LIGHT_NUMBER>
        <VICINITY>CHIOGGIA</VICINITY>
        <ITA_LIGHT_NAME>Diga N, estr</ITA_LIGHT_NAME>
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
        <NTC_LIGHTLISTPRODUCT>              
            <ITA_LIGHT_NUMBER>3429.2</ITA_LIGHT_NUMBER>              
            <VICINITY>CORIGLIANO CALABRO</VICINITY>
            <ITA_LIGHT_NAME>Ingresso bacino di evoluzione;Molo S, estr</ITA_LIGHT_NAME>
        </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>
        <ITA_LIGHT_NUMBER>3429.55</ITA_LIGHT_NUMBER>
        <VICINITY>CORIGLIANO CALABRO</VICINITY>
        <ITA_LIGHT_NAME>Darsena N.2;Banchina N.4, spigolo S</ITA_LIGHT_NAME>
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>
        <ITA_LIGHT_NUMBER>3427</ITA_LIGHT_NUMBER>
        <VICINITY>FIUME TRIONTO</VICINITY>
        <ITA_LIGHT_NAME>Impianto di maricoltura</ITA_LIGHT_NAME>
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>
        <ITA_LIGHT_NUMBER>3614.3</ITA_LIGHT_NUMBER>
        <VICINITY>FRIGOLE</VICINITY>
        <ITA_LIGHT_NAME>Area di protezione e sviluppo delle risorse biologiche marine;Boa B3</ITA_LIGHT_NAME>
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>          
<SECTION_CONTENT_LIST_ITEM>
    <NTC_LIGHTLISTPRODUCT>              
        <ITA_LIGHT_NUMBER>1577</ITA_LIGHT_NUMBER>
        <VICINITY>GENOVA</VICINITY>
        <ITA_LIGHT_NAME>Granarolo</ITA_LIGHT_NAME>
    </NTC_LIGHTLISTPRODUCT>
</SECTION_CONTENT_LIST_ITEM>

1 个答案:

答案 0 :(得分:1)

看起来您想要做的不仅仅是将数据排成行。看起来你想要对它们进行分组(因为,例如,ACCIAROLI出现两次,但你只想要一行)。

你真正需要注意的是这里称为Muenchian Grouping的技术,因为它比不断检查前面的元素更有效。

在您的情况下,您可以像这样定义一个键:

<xsl:key name="prod_by_vicinity" match="NTC_LIGHTLISTPRODUCT" use="VICINITY" />

我在这里对NTC_LIGHTLISTPRODUCT进行分组,因为这样可以更轻松地获取VICINITY以外的元素的其他值

然后,您将获得不同的VICINITY值,如下所示:

 <xsl:variable name="distinct" select="//NTC_LIGHTLISTPRODUCT[generate-id() = generate-id(key('prod_by_vicinity', VICINITY)[1])]" />

要开始生成行,您只需要选择此节点集中的前5个(或50个)节点(我在此处参数化了行数)

   <xsl:for-each select="$distinct[position() &lt;= $rows]">

要将产品放在第一个单元格中,将产品放在行中的第二个单元格中,您可以这样做:

 <xsl:apply-templates select="."/>
 <xsl:apply-templates select="$distinct[$pos + $rows]" />

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes" />
   <xsl:param name="rows" select="5" />
   <xsl:key name="prod_by_vicinity" match="NTC_LIGHTLISTPRODUCT" use="VICINITY" />

   <xsl:template match="/">
     <xsl:variable name="distinct" select="//NTC_LIGHTLISTPRODUCT[generate-id() = generate-id(key('prod_by_vicinity', VICINITY)[1])]" />
     <table border="1">
       <xsl:for-each select="$distinct[position() &lt;= $rows]">
         <xsl:variable name="pos" select="position()" />
         <tr>
           <xsl:apply-templates select="."/>
           <xsl:apply-templates select="$distinct[$pos + $rows]" />
         </tr>
       </xsl:for-each>      
     </table>
   </xsl:template>

   <xsl:template match="NTC_LIGHTLISTPRODUCT">
      <td>
         <xsl:value-of select="VICINITY" />
         <xsl:text> </xsl:text>
         <xsl:for-each select="key('prod_by_vicinity', VICINITY)">
            <xsl:if test="position() > 1"> - </xsl:if>
            <xsl:value-of select="ITA_LIGHT_NUMBER" />
         </xsl:for-each>
      </td>
   </xsl:template>
</xsl:stylesheet>

注意:我在这里做了一个很大的假设。我假设数据已经在输入XML中按VICINITY排序。如果它不是,那么它会变得更加复杂,你可能正在考虑必须执行两遍变换以在进行上述变换之前对其进行排序。