2017-07-19 2 views
0

Ceci est un suivi de ma précédente question. J'ai commencé avec une table grille qui prend le format:XSLT: Utiliser plusieurs touches pour créer une grille

A1,B1,C1 

A2,B2,C2 

A3,B3,C3 

Maintenant, ce tableau des résultats répète jusqu'à 5 fois en fonction de la valeur d'instance dans le dossier. Les valeurs dans les cellules seront différentes pour chaque instance de la table.

Le code XML avec lequel je travaille fournit une valeur de cellule par enregistrement avec les valeurs DayOfWeek (colonne), Stream (Row) et Instance (itération de table).

Grâce à un assistant précédent, j'ai maintenant XSLT qui me permet de créer une grille (colonnes x lignes). Toutefois lorsque j'ajoute une clé supplémentaire (ligne par instance) pour parcourir l'instance, le XSLT échoue.

Le résultat cible ressemblerait à ceci:

Instance 1 
A1,B1,C1 

A2, ,C2 

A3,B3,C3 

Instance 2 
D1,E1,F1 

D2, ,F2 

D3,E3,F3 

Il peut y avoir jusqu'à 5 cas, jusqu'à 7 jours de la semaine et un certain nombre de lignes.

MISE À JOUR J'ai mis à jour le XSLT suite à une contribution de Michael, mais je ne suis toujours pas là. Le résultat courant est

A1 A1 A1 A1 B1 B1 B1 C1 C1 C1 C1 
A2 A2 A2 A2   C2 C2 C2 C2 
A3 A3 A3 A3 B3 B3 B3 C3 C3 C3 C3 

A1 A1 A1 A1 B1 B1 B1 C1 C1 C1 C1 
A2 A2 A2 A2   C2 C2 C2 C2 
A3 A3 A3 A3 B3 B3 B3 C3 C3 C3 C3 

J'ai deux itérations de la table, mais ils contiennent les mêmes données, et les colonnes sont trop répéter plusieurs fois!

XSL:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="row-by-instance" match="DataRow" use="Instance" /> 

<xsl:key name="row-by-stream" match="DataRow" use="concat(Instance, '|', Stream)" /> 
<xsl:key name="row-by-day" match="DataRow" use="concat(Instance, '|', Stream,'|',DayOfWeek)" /> 

<xsl:template match="/QueryResults"> 
    <!-- a column for each distinct day of week --> 
    <xsl:variable name="columns" select="DataRow[generate-id() = generate-id(key('row-by-day',concat(Instance, '|', DayOfWeek))[1])]" /> 

    <xsl:for-each select="DataRow[count(. | key('row-by-instance', Instance)[1]) = 1]"> 
    <table border="1"> 
     <!-- a row for each distinct stream --> 
     <!--<xsl:for-each select="DataRow[count(. | key('row-by-stream', Instance)[1]) = 1]">--> 
     <xsl:for-each select="key('row-by-instance', Instance)[count(. | key('row-by-stream', concat(Instance, '|', Stream))[1]) = 1]"> 
      <xsl:variable name="stream" select="key('row-by-stream', concat(Instance, '|', Stream))" /> 
      <tr> 
       <!-- a cell for each column --> 
       <xsl:for-each select="key('row-by-instance', Instance)[count(. | key('row-by-day', concat(Instance, '|', Stream,'|',DayOfWeek))[1]) = 1]"> 
        <xsl:sort select="DayOfWeek" data-type="number" order="ascending"/> 
        <td> 
         <xsl:value-of select="$stream[DayOfWeek = current()/DayOfWeek]/DisplayStuff" /> 
        </td> 
       </xsl:for-each> 
      </tr> 
     </xsl:for-each> 
    </table> 
    </xsl:for-each> 
</xsl:template> 

XML:

<?xml version="1.0" encoding="UTF-8"?> 
<QueryResults> 
<DataRow> 
    <Instance>1</Instance> 
    <Stream>1</Stream> 
    <DayOfWeek>1</DayOfWeek> 
    <DisplayStuff>A1</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Instance>1</Instance> 
    <Stream>1</Stream> 
    <DayOfWeek>2</DayOfWeek> 
    <DisplayStuff>B1</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Instance>1</Instance> 
    <Stream>1</Stream> 
    <DayOfWeek>3</DayOfWeek> 
    <DisplayStuff>C1</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Instance>1</Instance> 
    <Stream>2</Stream> 
    <DayOfWeek>1</DayOfWeek> 
    <DisplayStuff>A2</DisplayStuff> 
</DataRow> 

<DataRow> 
    <Instance>1</Instance> 
    <Stream>2</Stream> 
    <DayOfWeek>3</DayOfWeek> 
    <DisplayStuff>C2</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Instance>1</Instance> 
    <Stream>3</Stream> 
    <DayOfWeek>1</DayOfWeek> 
    <DisplayStuff>A3</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Instance>1</Instance> 
    <Stream>3</Stream> 
    <DayOfWeek>2</DayOfWeek> 
    <DisplayStuff>B3</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Instance>1</Instance> 
    <Stream>3</Stream> 
    <DayOfWeek>3</DayOfWeek> 
    <DisplayStuff>C3</DisplayStuff> 
</DataRow> 
    <DataRow> 
     <Instance>2</Instance> 
     <Stream>1</Stream> 
     <DayOfWeek>1</DayOfWeek> 
     <DisplayStuff>D1</DisplayStuff> 
    </DataRow> 
    <DataRow> 
     <Instance>2</Instance> 
     <Stream>1</Stream> 
     <DayOfWeek>2</DayOfWeek> 
     <DisplayStuff>E1</DisplayStuff> 
    </DataRow> 
    <DataRow> 
     <Instance>2</Instance> 
     <Stream>1</Stream> 
     <DayOfWeek>3</DayOfWeek> 
     <DisplayStuff>F1</DisplayStuff> 
    </DataRow> 
    <DataRow> 
     <Instance>2</Instance> 
     <Stream>2</Stream> 
     <DayOfWeek>1</DayOfWeek> 
     <DisplayStuff>D2</DisplayStuff> 
    </DataRow> 

    <DataRow> 
     <Instance>2</Instance> 
     <Stream>2</Stream> 
     <DayOfWeek>3</DayOfWeek> 
     <DisplayStuff>E2</DisplayStuff> 
    </DataRow> 
    <DataRow> 
     <Instance>2</Instance> 
     <Stream>3</Stream> 
     <DayOfWeek>1</DayOfWeek> 
     <DisplayStuff>D3</DisplayStuff> 
    </DataRow> 
    <DataRow> 
     <Instance>2</Instance> 
     <Stream>3</Stream> 
     <DayOfWeek>2</DayOfWeek> 
     <DisplayStuff>E3</DisplayStuff> 
    </DataRow> 
    <DataRow> 
     <Instance>2</Instance> 
     <Stream>3</Stream> 
     <DayOfWeek>3</DayOfWeek> 
     <DisplayStuff>F3</DisplayStuff> 
    </DataRow>  
</QueryResults> 
+1

Ce que vous entendez par instance n'est pas clair. Quel serait le résultat attendu de la transformation de l'exemple d'entrée donné? –

+0

Toutes mes excuses - J'ai ajouté une sortie prévue et un peu plus de détails. – iainc

+0

Je ne comprends pas votre sortie. Est-ce censé être une table distincte pour chaque instance, ou quoi? –

Répondre

0

Eh bien, vous avez pris plusieurs mal tourne sur le chemin. Voir si cela vous aide à obtenir sur la bonne voie:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="row-by-instance" match="DataRow" use="Instance" /> 
<xsl:key name="row-by-day" match="DataRow" use="DayOfWeek" /> 
<xsl:key name="row-by-stream" match="DataRow" use="concat(Instance, '|', Stream)" /> 

<xsl:template match="/QueryResults"> 
    <!-- a column for each distinct day of week (in any instance) --> 
    <xsl:variable name="columns" select="DataRow[generate-id() = generate-id(key('row-by-day', DayOfWeek)[1])]" /> 
    <!-- a table for each distinct instance --> 
    <xsl:for-each select="DataRow[count(. | key('row-by-instance', Instance)[1]) = 1]"> 
     <xsl:variable name="instance-rows" select="key('row-by-instance', Instance)" /> 
     <table border="1"> 
      <!-- a row for each distinct stream in this instance --> 
      <xsl:for-each select="$instance-rows[generate-id() = generate-id(key('row-by-stream', concat(Instance, '|', Stream))[1])]"> 
       <xsl:variable name="stream-rows" select="key('row-by-stream', concat(Instance, '|', Stream))" /> 
       <tr> 
        <!-- a cell for each column --> 
        <xsl:for-each select="$columns"> 
         <xsl:sort select="DayOfWeek" data-type="number" order="ascending"/> 
         <td> 
          <xsl:value-of select="$stream-rows[DayOfWeek = current()/DayOfWeek]/DisplayStuff" /> 
         </td> 
        </xsl:for-each> 
       </tr> 
      </xsl:for-each> 
     </table> 
    </xsl:for-each> 
</xsl:template>  

</xsl:stylesheet> 

Notez que cela génère un ensemble unique de colonnes pour toutes les tables, afin que les tables aligneront. Si vous souhaitez que chaque table ait ses propres colonnes (ignorer les jours de la semaine pour lesquels elle n'a pas de données), vous devrez faire les choses différemment. Plus important encore, vous devrez inclure Instance dans la clé row-by-day.