Question

J'ai besoin d'afficher certains contenus XML sous forme de tableau (XSL-FO pour les rapports PDF), et pas toutes les colonnes à afficher sont présents en XML source. Alors, je me demandais s'il y a un moyen de transformer XML source en intégrant des colonnes supplémentaires en fonction de certaines valeurs d'éléments, et traiter ensuite le XML résultant pour afficher le contenu?

À titre d'exemple, pour les données source:

<projectteam>
  <member>
    <name>John Doe</name>
    <role>dev</role>
 <hrs>100</hrs>
  </member>
  <member>
    <name>Paul Coder</name>
    <role>dev</role>
 <hrs>40</hrs>
  </member>
  <member>
    <name>Henry Tester</name>
    <role>qa</role>
 <hrs>80</hrs>
  </member>
  <member>
    <name>Peter Tester</name>
    <role>qa</role>
 <hrs>40</hrs>
  </member>
</projectteam>

Je voudrais les données à afficher comme:

Name         Role  Dev   QA
---------------------------
John Doe     dev   100  
Paul Coder   dev    40
Henry Tester qa          80
Peter Tester qa          40
---------------------------
Role Totals:       140  120
---------------------------

Je voudrais savoir si je peux utiliser quelque chose comme:

    <xsl:element name="{role}">
      <xsl:value-of select="member/hrs"/>
    </xsl:element>

Alors que je peux intégrer des éléments 100 et ainsi de suite au moment de l'exécution au cours de premier passage, puis utilisez le code XML résultant pour afficher les données nouvelles « dev » columsn et « qa », de cette façon, le calcul des totaux pour chaque type de rôle sera beaucoup plus simple (Par exemple, "somme (preceding-sibling :: élément / dev)". Pour la colonne dev), et les données pour chaque cellule « dev » et « colums qa » pourrait simplement être la valeur de ces balises respectivement.

Il a obtenu les résultats souhaités à la dure à l'aide suivantes stylesheet (page mise en forme détails omis de le garder bref), mais ne suis pas convaincu que c'est la solution apt.

    ...
              <fo:table-body>
      <!-- fills table rows -->
                <xsl:apply-templates select="member"/>

      <!-- dislpay totals for each role -->
      <fo:table-row height="12pt" border-bottom="1pt solid black">
      <fo:table-cell number-columns-spanned="2">
        <fo:block>Role Totals:</fo:block>
      </fo:table-cell>

      <fo:table-cell text-align="right">
        <xsl:call-template name="RoleTotals">
          <xsl:with-param name="node" select="//member[1]"/>
         <xsl:with-param name="roleName" select="'dev'"/>
        </xsl:call-template>
      </fo:table-cell>
      <fo:table-cell text-align="right">
        <xsl:call-template name="RoleTotals">
          <xsl:with-param name="node" select="//member[1]"/>
         <xsl:with-param name="roleName" select="'qa'"/>
        </xsl:call-template>
      </fo:table-cell>
      </fo:table-row>
              </fo:table-body>
    ...
    </fo:root>
  </xsl:template>

  <xsl:template match="member">
  <fo:table-row border-bottom="1pt solid black">
      <fo:table-cell> <fo:block> <xsl:value-of select="name"/></fo:block></fo:table-cell>
      <fo:table-cell> <fo:block> <xsl:value-of select="role"/></fo:block></fo:table-cell>
      <fo:table-cell text-align="right">
        <fo:block> 
      <xsl:if test="role = 'dev'"><xsl:value-of select="hrs"/></xsl:if>
  </fo:block>
      </fo:table-cell>
      <fo:table-cell text-align="right">
        <fo:block> 
      <xsl:if test="role = 'qa'"><xsl:value-of select="hrs"/></xsl:if>
  </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </xsl:template>

  <xsl:template name="RoleTotals">
    <xsl:param name="node"/>
    <xsl:param name="roleName"/>
    <xsl:param name="RT" select="0"/>
    <xsl:variable name="newRT">
    <xsl:choose>
      <xsl:when test="$node/role = $roleName">
         <xsl:value-of select="$RT + $node/hrs"/>
      </xsl:when>
      <xsl:otherwise><xsl:value-of select="$RT"/></xsl:otherwise>
    </xsl:choose>
    </xsl:variable>
   <xsl:choose>
     <xsl:when test="$node/following-sibling::member">
      <xsl:call-template name="RoleTotals">
        <xsl:with-param name="node" select="$node/following-sibling::member[1]"/>
        <xsl:with-param name="roleName" select="$roleName"/>
        <xsl:with-param name="RT" select="$newRT"/>
      </xsl:call-template>
     </xsl:when>
     <xsl:otherwise>
      <fo:block><xsl:value-of select="$newRT"/></fo:block>
     </xsl:otherwise>
   </xsl:choose> 
  </xsl:template>
Était-ce utile?

La solution

Oui, vous pouvez.

Pour répondre à votre question. Je n'ai pas lu l'énorme feuille de style, pour être vrai.

Autres conseils

Que se passerait-il si plus de rôles d'emploi, autres que Dev et QA se sont ajoutés? Est-ce que votre stylesheet être en mesure de faire face? Peut-être que vous pouvez utiliser Muenchian groupe afin d'obtenir tous les rôles possibles dans la feuille de style, puis générer des colonnes pour chaque rôle possible dynamiquement?

<xsl:key name="roles" match="role" use="."/>

<xsl:template match="/projectteam">
 <table border="1">
  <tr>
   <td>Name</td>
   <td>Role</td>
   <xsl:for-each select="member[generate-id(role) = generate-id(key('roles', role)[1])]">
    <td>
     <xsl:value-of select="role"/>
    </td>
   </xsl:for-each>
  </tr>
  <xsl:apply-templates select="member"/>
 </table>
</xsl:template>

<xsl:template match="member">
 <xsl:variable name="currentrole" select="role"/>
 <xsl:variable name="currenthrs" select="hrs"/>
 <tr>
  <td>
   <xsl:value-of select="name"/>
  </td>
  <td>
   <xsl:value-of select="role"/>
  </td>
  <xsl:for-each select="/projectteam/member[generate-id(role) = generate-id(key('roles', role)[1])]">
   <td>
    <xsl:choose>
     <xsl:when test="$currentrole = role">
      <xsl:value-of select="$currenthrs"/>
     </xsl:when>
    </xsl:choose>
   </td>
  </xsl:for-each>
 </tr>
</xsl:template>

Je suis en HTML émis, non XSL-FO, mais peut-être que cela vous donne l'idée générale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top