2017-07-14 2 views
-1

je dois transformer XML en une table grille qui prend le format:XSLT: À l'aide d'une clé pour traverser référence une deuxième clé

A1,B1,C1 

A2,B2,C2 

A3,B3,C3 

Le XML que je travaille avec fournit une valeur de la cellule par enregistrement, mais chaque enregistrement fournit une valeur DayOfWeek (colonne) et Stream (Row).

J'ai fait une simple transformation XSLT en utilisant deux clés, une pour Stream et une pour DayOfWeek. Ceux-ci fonctionnent avec succès en ce que j'ai 3 lignes, une pour chaque flux, et 3 colonnes, une pour chaque jour de la semaine. Cependant, le contenu est juste la première rangée répétée (c.-à-

A1,B1,C1, 
A1,B1,C1, 
A1,B1,C1 

Comment puis-je sélectionner DisplayStuff dans une cellule de table en fonction des deux critères clés

Voici mon XSLT:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes" encoding="us-ascii" /> 
    <xsl:key name="DayOfWeek1" match="DataRow" use="DayOfWeek" /> 
    <xsl:key name="Stream1" match="DataRow" use="Stream" /> 
    <xsl:template match="QueryResults"> 
     <table> 
    <xsl:for-each select="//DataRow[generate-id() = generate-id(key('Stream1',Stream)[1])]"> 
     <tr style="border: 1px solid black;" class="scrolling"> 
      <xsl:for-each select="//DataRow[generate-id() = generate-id(key('DayOfWeek1',DayOfWeek)[1])]"> 


       <td style="border: 1px solid black;" width="100px"> 
        <xsl:value-of select="DisplayStuff" /> 
       </td> 

      </xsl:for-each> 
     </tr> 
    </xsl:for-each> 
    </table> 
    </xsl:template> 
</xsl:stylesheet> 

XML :

<?xml version="1.0" encoding="UTF-8"?> 
<QueryResults> 
<DataRow> 
    <Stream>1</Stream> 
    <DayOfWeek>1</DayOfWeek> 
    <DisplayStuff>A1</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Stream>1</Stream> 
    <DayOfWeek>2</DayOfWeek> 
    <DisplayStuff>B1</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Stream>1</Stream> 
    <DayOfWeek>3</DayOfWeek> 
    <DisplayStuff>C1</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Stream>2</Stream> 
    <DayOfWeek>1</DayOfWeek> 
    <DisplayStuff>A2</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Stream>2</Stream> 
    <DayOfWeek>2</DayOfWeek> 
    <DisplayStuff>B2</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Stream>2</Stream> 
    <DayOfWeek>3</DayOfWeek> 
    <DisplayStuff>C2</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Stream>3</Stream> 
    <DayOfWeek>1</DayOfWeek> 
    <DisplayStuff>A3</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Stream>3</Stream> 
    <DayOfWeek>2</DayOfWeek> 
    <DisplayStuff>B3</DisplayStuff> 
</DataRow> 
<DataRow> 
    <Stream>3</Stream> 
    <DayOfWeek>3</DayOfWeek> 
    <DisplayStuff>C3</DisplayStuff> 
</DataRow> 
</QueryResults> 
+0

Peut-être que ce n'est qu'un mauvais exemple, mais si vous savez que vous avez affaire à une grille 3x3 (ou 3xn), pourquoi avez-vous besoin de clés du tout? Créez simplement une ligne pour chaque groupe de 3 enregistrements et une cellule pour chaque enregistrement de ce groupe - voir, par exemple, https://stackoverflow.com/a/26573496/3016153. –

+0

c'est le problème. la table est dynamique. les cliniques peuvent fonctionner jusqu'à 7 jours par semaine et les jours ne doivent pas être consécutifs. il peut y avoir jusqu'à 10 flux cliniques. – iainc

+0

c'est le problème. la table est dynamique. les cliniques peuvent fonctionner jusqu'à 7 jours par semaine et les jours ne doivent pas être consécutifs. il peut y avoir jusqu'à 10 flux cliniques. – iainc

Répondre

0

Essayez cette façon

0?

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-day" match="DataRow" use="DayOfWeek" /> 
<xsl:key name="row-by-stream" match="DataRow" use="Stream" /> 

<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', DayOfWeek)[1])]" /> 
    <table border="1"> 
     <!-- a row for each distinct stream --> 
     <xsl:for-each select="DataRow[generate-id() = generate-id(key('row-by-stream', Stream)[1])]"> 
      <xsl:variable name="stream" select="key('row-by-stream', 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[DayOfWeek = current()/DayOfWeek]/DisplayStuff" /> 
        </td> 
       </xsl:for-each> 
      </tr> 
     </xsl:for-each> 
    </table> 
</xsl:template> 

</xsl:stylesheet> 

Notez que cela suppose qu'il y aura au plus un DataRow pour chaque intersection de Stream et DayOfWeek.