2010-10-20 7 views
1

J'ai quelques xml dans le format suivant:xsl Transformer XML

<fileExport> 
    <rows> 
    <row id="0"> 
     <columns> 
     <column id="0"> 
      <name>Date Time</name> 
      <value>2010-10-2 23:00:00 GMT</value> 
     </column> 
     <column id="1"> 
      <name>Primary</name> 
      <value>100.1</value> 
     </column> 
     <column id="2"> 
      <name>Manual</name> 
      <value>20.5</value> 
     </column> 
     ... 
     </columns> 
    </row> 
    <row id="1"> 
     <columns> 
     <column id="0"> 
      <name>Date Time</name> 
      <value>2010-10-3 00:00:00 GMT</value> 
     </column> 
     <column id="1"> 
      <name>Primary</name> 
      <value>110.5</value> 
     </column> 
     ... 
     <column id="2"> 
      <name>Manual</name> 
      <value>23.1</value> 
     </column> 
     </columns> 
    </row> 
    </rows> 
</fileExport> 

Maintenant, l'idée est de transformer ce texte au format CSV. Tout semble fonctionner correctement - mais j'ai 32 colonnes pour chaque rangée dans le dessus. Pour transformer ce au format CSV, j'utilise le XSL suivant:

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="text" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
    <xsl:for-each select="//rows/row"> 
     <!-- Now add a new row for each column --> 

     <!-- first row in file for this row in table --> 
     <xsl:text>A</xsl:text> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="columns/column[name='Date Time']/value"/> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="columns/column[name='Primary']/value"/> 
     <xsl:text>,</xsl:text> 
     <xsl:text>P</xsl:text> 
     <xsl:text>&#xA;</xsl:text> 

     <!-- second row in file for this row in table --> 
     <xsl:text>A</xsl:text> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="columns/column[name='Date Time']/value"/> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="columns/column[name='Manual']/value"/> 
     <xsl:text>,</xsl:text> 
     <xsl:text>M</xsl:text> 
     <xsl:text>&#xA;</xsl:text> 

     ... now repeat for the next 30 columns ... 

     <!-- next row in table--> 
    </xsl:for-each> 
    <xsl:text>&lt;EOF&gt;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 

Maintenant que nous donne la sortie:

A,2010-10-2 23:00:00 GMT,100.1,P 
A,2010-10-2 23:00:00 GMT,20.5,M 
A,2010-10-3 00:00:00 GMT,110.5,P 
A,2010-10-3 00:00:00 GMT,23.1,M 
<EOF> 

Question est, ayant 32 ou si des colonnes dans le fichier XML est-il possible de raccourcir le XSL requis pour atteindre les mêmes résultats?

Des idées?

Merci,

Andez

Répondre

1

Cela pourrait-il aider?

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="text" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/fileExport"> 
    <xsl:for-each select="rows/row"> 
     <xsl:variable name="date" select="columns/column[name='Date Time']/value"/> 
     <xsl:for-each select="columns/column"> 
      <xsl:if test="name!='Date Time'"> 
       <xsl:text>A</xsl:text> 
       <xsl:text>,</xsl:text> 
       <xsl:value-of select="$date"/> 
       <xsl:text>,</xsl:text> 
       <xsl:value-of select="value"/> 
       <xsl:text>,</xsl:text> 
       <xsl:choose> 
        <xsl:when test="name='Primary'">P</xsl:when> 
        <xsl:when test="name='Manual'">M</xsl:when> 
        .... 
       </xsl:choose> 
       <xsl:text>&#xA;</xsl:text> 
       </xsl:if> 
     </xsl:for-each> 
    </xsl:for-each> 
    <xsl:text>&lt;EOF&gt;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Je suppose que cela ressemble à cela fonctionnera aussi. – Andez

+0

quelle est la logique avec les dernières données de terrain l'hypothèse primaire est la première lettre ou le nom, mais j'étais inquiet de variantes plus bizarres – dvhh

4

Cette feuille de style:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" /> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="row"> 
     <xsl:text>A</xsl:text> 
     <xsl:apply-templates/> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 
    <xsl:template match="value"> 
     <xsl:value-of select="concat(',',.)"/> 
    </xsl:template> 
    <xsl:template match="column[name='Primary' or name='Manual']"> 
     <xsl:apply-templates/> 
     <xsl:value-of select="concat(',',substring(name,1,1))"/> 
    </xsl:template> 
    <xsl:template match="row[position() mod 2]/*/column[name='Manual']| 
         row[position() mod 2 = 0]/*/column[name='Primary']| 
         text()" priority="1"/> 
</xsl:stylesheet> 

Sortie:

A,2010-10-2 23:00:00 GMT,100.1,P 
A,2010-10-3 00:00:00 GMT,23.1,M 
+0

+1 belle implémentation, l'utilisation de modèles de correspondance de modèle pour le traitement conditionnel. – LarsH

+0

On dirait mieux que ce que j'ai imaginé. Pensez que je vais vérifier les modèles et faire un peu plus de lecture en premier. – Andez

+0

@Andez: Pour comprendre cela, vous devez également connaître les [règles intégrées] (http://www.w3.org/TR/xslt#built-in-rule). La signification de tout ceci est: * 'row' à 'A'-childs result-NL; 'value' à ',' - valeur de chaîne; La colonne 'Primary' ou 'Manual' donne le résultat de l'enfant - ',' - première lettre de 'name'; ne pas traiter une colonne 'Manual' pour une ligne impaire 'row', ni une colonne 'Primary' pour même une ligne, ni des nœuds de texte *. –