2015-06-01 45 views
0

創建固定數量的列字母索引我有一個這樣的XML:在XSLT 2.0

<xml version="1.0" encoding="UTF-8"?> 
<countries> 
    <country> 
     <name>Latvia</name> 
    </country> 
    <country> 
     <name>USA</name> 
    </country> 
    <country> 
     <name>Australia</name> 
    </country> 
    <country> 
     <name>Indonesia</name> 
    </country> 
    <country> 
     <name>UK</name> 
    </country> 
    <country> 
     <name>India</name> 
    </country> 
    <country> 
     <name>Argentina</name> 
    </country> 
    <country> 
     <name>Chile</name> 
    </country> 
    <country> 
     <name>Singapore</name> 
    </country> 
    <country> 
     <name>New Zeland</name> 
    </country> 
    <country> 
     <name>Kenya</name> 
    </country> 
    <country> 
     <name>Zambia</name> 
    </country> 
    <country> 
     <name>Tunisia</name> 
    </country> 
</countries> 

現在我想在3列創建國家字母索引。每列將包含alpha的數量,作爲出現的起始字母的三分之一以及相應的國家/地區。

最後一欄可以讓他們的休息,如果起始字母存在的數量不發生由3

例如整除是,在這裏我們的國家名稱以L,C,U,A,I, S,N,K,Z和T.

安排好後:ACIKLNSTUZ

現在,我的索引將有:

  Column1: A, C and I countries 

     Column2: K, L and N countries 

     Column3: S, T, U and Z countries 

因此所需的輸出是:

<countries> 
    <column1> 
    <A> 
     <country> 
      <name>Argentina</name> 
     </country> 
     <country> 
      <name>Australia</name> 
     </country> 
    </A> 
    <C> 
     <country> 
      <name>Chile</name> 
     </country> 
    </C> 
    <I> 
     <country> 
      <name>India</name> 
     </country> 
     <country> 
      <name>Indonesia</name> 
     </country> 
    </I> 
    </column1> 

    <column2> 
    <K> 
     <country> 
      <name>Kenya</name> 
     </country>  
    </K> 
    <L> 
     <country> 
      <name>Latvia</name> 
     </country> 

    </L> 
    <N> 
     <country> 
      <name>New Zeland</name> 
     </country> 
    </N> 
    </column2> 

    <column3> 
    <S> 
     <country> 
      <name>Singapore</name> 
     </country>  
    </S> 
    <T> 
     <country> 
      <name>Tunisia</name> 
     </country> 

    </T> 
    <U> 
     <country> 
      <name>UK</name> 
     </country> 
     <country> 
      <name>USA</name> 
     </country> 
    </U> 
    <Z> 
     <country> 
      <name>Zambia</name> 
     </country> 
    </Z> 
    </column3> 
</countries> 

請大家幫忙。我正在使用xslt 2.0。

+0

恕我直言,你應該張貼您的新需求的新問題。 –

+0

完成。這裏的鏈接 - http://stackoverflow.com/questions/30614777/adjust-an-alphabetical-index-from-xml-grouping-to-make-columns-equal 謝謝! –

回答

0

我想出了

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

<xsl:output indent="yes"/> 

<xsl:param name="size" select="3"/> 

<xsl:template match="countries"> 
    <xsl:copy> 
     <xsl:variable name="groups"> 
     <xsl:for-each-group select="country" group-by="substring(name, 1, 1)"> 
      <xsl:sort select="current-grouping-key()"/> 
      <xsl:element name="{current-grouping-key()}"> 
       <xsl:copy-of select="current-group()"/> 
      </xsl:element>    
     </xsl:for-each-group> 
     </xsl:variable> 
     <xsl:for-each select="$groups/*[position() mod $size eq 1]"> 
     <xsl:if test="position() le $size"> 
      <xsl:variable name="pos" select="position()"/> 
      <xsl:element name="column{position()}"> 
      <xsl:copy-of select="., following-sibling::*[if ($pos eq $size) then true() else (position() lt $size)]"/> 
      </xsl:element> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 


</xsl:transform> 
1

我會考慮這樣做的兩個過程,第一次按字母順序排序,給出一系列的元素,然後將這個序列劃分成列。

<xsl:variable name="groups" as="element()*"> 
    <xsl:for-each-group select="/countries/country" group-by="substring(name, 1, 1)"> 
    <!-- sort groups alphabetically --> 
    <xsl:sort select="current-grouping-key()" /> 
    <xsl:element name="{current-grouping-key()}"> 
     <xsl:perform-sort select="current-group()"> 
     <!-- sort names within each group --> 
     <xsl:sort select="name" /> 
     </xsl:perform-sort> 
    </xsl:element> 
    </xsl:for-each-group> 
</xsl:variable> 

<xsl:variable name="numPerCol" select="count($groups) div 3" /> 
<column1> 
    <xsl:sequence select="$groups[position() le $numPerCol]"/> 
</column1> 
<column2> 
    <xsl:sequence select="$groups[position() gt $numPerCol and position() le (2*$numPerCol)]" /> 
</column2> 
<column3> 
    <xsl:sequence select="$groups[position() gt (2*$numPerCol)]" /> 
</column3>