2011-12-02 20 views
1

ノードのコレクションを2つの要素でループし、各グループに対して2つの列テーブルを出力します。表は、アルファベット順、最初の列、次に2番目の列にソートされます。最初の要素をグループ化して、2つの列の各2番目の要素を出力します。for-each内で任意の兄弟を選択する

例データソース:

<ArrayOfEIS_CT_AssignmentByRegion 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <EIS_CT_AssignmentByRegion> 
     <Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region>    
     <CountryName>IRAQ</CountryName>    
    </EIS_CT_AssignmentByRegion> 
    <EIS_CT_AssignmentByRegion> 
     <Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region> 
     <CountryName>JORDAN</CountryName> 
    </EIS_CT_AssignmentByRegion> 
    <EIS_CT_AssignmentByRegion> 
     <Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region> 
     <CountryName>GAZA AND WEST BANK</CountryName> 
    </EIS_CT_AssignmentByRegion> 
    <EIS_CT_AssignmentByRegion> 
     <Region>MIDDLE EAST, NORTH AFRICA and EUROPE</Region> 
     <CountryName>KUWAIT</CountryName> 
    </EIS_CT_AssignmentByRegion>  
    <EIS_CT_AssignmentByRegion> 
     <Region>SUBSAHARAN AFRICA</Region> 
     <CountryName>TOGO</CountryName> 
    </EIS_CT_AssignmentByRegion> 
    <EIS_CT_AssignmentByRegion> 
     <Region>SUBSAHARAN AFRICA</Region> 
     <CountryName>ZIMBABWE</CountryName> 
    </EIS_CT_AssignmentByRegion> 
    <EIS_CT_AssignmentByRegion> 
     <Region>SUBSAHARAN AFRICA</Region> 
     <CountryName>ZAMBIA</CountryName> 
    </EIS_CT_AssignmentByRegion> 
    <EIS_CT_AssignmentByRegion> 
     <Region>SUBSAHARAN AFRICA</Region> 
     <CountryName>UGANDA</CountryName> 
    </EIS_CT_AssignmentByRegion> 
</ArrayOfEIS_CT_AssignmentByRegion> 

はXSLT:

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:w="http://schemas.microsoft.com/office/word/2006/wordml"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>  
    <xsl:key name="list-by-region" match="EIS_CT_AssignmentByRegion" use="concat(generate-id(..), '|', Region)"/> 
    <xsl:template match="/ArrayOfEIS_CT_AssignmentByRegion"> 
     <html> 
      <body> 
       <xsl:for-each select="EIS_CT_AssignmentByRegion[generate-id() = generate-id(key('list-by-region', concat(generate-id(..), '|', Region))[1])]">      
        <xsl:sort select="Region" /> 
        <xsl:sort select="CountryName" /> 
        <xsl:variable name="halfIndex" select="floor(count(key('list-by-region', concat(generate-id(..), '|', Region))) div 2)" /> 
        <table> 
         <thead> 
          <tr> 
           <th colspan="2"> 
            <xsl:value-of select="Region" /> 
           </th> 
          </tr> 
         </thead> 
         <tbody> 
          <xsl:for-each select="key('list-by-region', concat(generate-id(..), '|', Region))"> 
           <xsl:sort select="CountryName" /> 
           <xsl:variable name="countryColumn2" select="following-sibling::*[position() = $halfIndex]" /> 
           <xsl:if test="position() &lt;= $halfIndex"> 
            <tr> 
             <td> 
              <xsl:value-of select="CountryName" /> 
             </td> 
             <td> 
              <xsl:value-of select="$countryColumn2" /> 
             </td> 
            </tr> 
           </xsl:if> 
          </xsl:for-each> 
         </tbody> 
        </table> 
       </xsl:for-each> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

私が欲しいの出力はこれです:

<html> 
    <body> 
    <table> 
     <thead> 
      <tr> 
       <th colspan="2"> 
        MIDDLE EAST, NORTH AFRICA and EUROPE 
       </th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
       <td> 
        GAZA AND WEST BANK 
       </td> 
       <td> 
        JORDAN 
       </td> 
      </tr> 
      <tr> 
       <td> 
        IRAQ 
       </td> 
       <td> 
        KUWAIT 
       </td> 
      </tr> 
     </tbody> 
    </table> 
    <table> 
     <thead> 
      <tr> 
       <th colspan="2"> 
        SUBSAHARAN AFRICA 
       </th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
       <td> 
        TOGO 
       </td> 
       <td> 
        ZAMBIA 
       </td> 
      </tr> 
      <tr> 
       <td> 
        UGANDA 
       </td> 
       <td> 
        ZIMBABWE 
       </td> 
      </tr> 
     </tbody> 
    </table> 
    </body> 
</html> 

私のアプローチは、各グループの唯一のプロセスの半分になり、後半から国を選択し、2番目の列に出力します。私の問題は、いくつかのグループの場合、間違った国が選択されていることです。多くの場合、別のグループの国が選択されています。

テストのために、すべての国を1列で順番に出力していますが、グループ分けされて正しくソートされています。この行は、いくつかのグループでは、現在のコンテキストを残しておきます。何か案は?ありがとう。いくつかのグループのための

答えて

1
<xsl:variable name="countryColumn2"  
    select="following-sibling::*[position() = $halfIndex]" /> 

、兄弟 ノードを選択するための現在のコンテキストを残します。何か案は?

良い質問、+1。

<xsl:sort>でソートしても、元の兄弟関係はXMLドキュメント内のノード間で変更されません。

は、したがって、2つのノードに対して:node1とその次の兄弟node2,node1もののは、ソートの結果として、node2node1の次の兄弟であることが依然として真であるnode2後に来ます。

ソリューション

  1. パス1:出力の一時的なツリー内のノード間の兄弟関係が正確に彼らのソート順を反映し、このツリー内のソート結果。

  2. pass2:最初のパスの結果を第2パスで処理し続けます。これで、兄弟軸を意図した方法で使用できます。

+0

ありがとう、素敵な明確な説明。今、完璧な意味合いがあります。私はxslt 1.0を使用しており、拡張機能を使用したくないので、私は2つのパスのテクニックを使用しませんでした。しかし、私はソースXMLのコントロールがあるので、私は同じ結果を達成するために私のソートを行った。 –

+0

@SteveMallory:どうぞよろしくお願いいたします。拡張に関しては、exslt:node-setはほとんどのXSLT 1.0プロセッサで実装されています。 –

関連する問題