2009-09-28 5 views
2

J'ai besoin d'afficher certaines données sous forme de tableau, et je préférerais utiliser multi-pass xslt en utilisant node-set() afin que je puisse éviter de déployer des outils supplémentaires (comme xsltproc). En ce moment, je suis en mesure d'effectuer la tâche requise en deux étapes iEAide avec XSLT multi-passes utilisant node-set()

Étape 1: convertir XML-1 à Xml-2 en utilisant le modèle d'identité (xsl: copie, en utilisant xsl: élément ajouter des éléments dynamiques ' dev 'et' qa`):

<projectteam> 
    <member> 
    <name>John</name> 
    <role>dev</role> 
    <hrs>100</hrs> 
    </member> 
    <member> 
    <name>Peter</name> 
    <role>qa</role> 
    <hrs>80</hrs> 
    </member> 
</projectteam> 

pour

<projectteam> 
    <member> 
    <name>John</name> 
    <dev>100</dev> 
    </member> 
    <member> 
    <name>Peter</name> 
    <qa>80</qa> 
    </member> 
<projectteam> 

et puis, utilisez une autre feuille de style XSLT-FO pour transformer XML # 2 dans un document PDF avec la mise en page nécessaire:

 
name | dev | qa | 
----------------- 
John | 100 | | 
Peter|  | 80 | 
----------------- 
Total| 100 | 80 | 

J'ai essayé d'utiliser node-set() (à tort je suppose) de combiner les deux étapes, mais cela ne fonctionnerait pas le résultat que je reçois est la suivante:

 
name | dev | qa | 
----------------- 
Total| 0 | 0 | 

stylesheet-1: convertit XML-1 à XML-2, importe une autre feuille de style 'projDisplay.xsl', utilise node-set() pour appeler la feuille de style importée, mais les données ne sont pas affichées?

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format" 
    xmlns:exslt="http://exslt.org/common" 
> 

    <!-- import stylesheet to display XML-2 in tabular form --> 
    <xsl:import href="projDisplay.xsl"/> 

    <xsl:template match="/"> 
    <fo:root> 
     <xsl:apply-templates/> 
    </fo:root> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
    <xsl:variable name="newXmlData"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:variable> 

    <!-- ==> This is where my problem is - it goes to the template defined in --> 
    <!-- projDisplay.xsl (xslt-fo, pretty big one with page layout etc. hence --> 
    <!-- not included here, but it works on its own though) as I can see the --> 
    <!-- table header, and an empty totals row, but non of the rows are displayed --> 

    <xsl:apply-templates 
     select="exslt:node-set($newXmlData)/projectteam" mode="display" 
    /> 
    </xsl:template> 

    <!-- replace element 'role' with a new element - role name (i.e. dev or qa) --> 
    <!-- and set its value as 'hrs            --> 
    <xsl:template match="role"> 
    <xsl:element name="{.}"> <xsl:value-of select="../hrs"/> </xsl:element> 
    </xsl:template> 

    <!-- eliminate element 'hrs' --> 
    <xsl:template match="hrs"/> 
</xsl:stylesheet> 

La section commentée dans la feuille de style ne me semble pas correcte. Toutes les suggestions sur la façon de le corriger?

Merci!

+0

Qu'advient-il si vous utilisez simplement 'select =: (sans'/projectteam') '' dans apply-templates' 'EXSLT ensemble de nœuds (newXmlData $)? –

+0

Essayé, et cela ne fonctionne pas. –

+0

Pouvez-vous essayer ma nouvelle réponse? Je n'ai pas de XSLT-FO à tester avec, et je n'ai pas projDisplay.xsl non plus, donc c'est un peu d'essai et d'erreur pour moi. – Tomalak

Répondre

3

est ici la solution qui fonctionne. Il est basé sur la solution originale de Tomalak avec quelques modifications mineures (comme les drapeaux de mode, etc.) Encore une fois, merci à Tomalak !!

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exslt="http://exslt.org/common" 
    version="1.0"> 

<xsl:import href="projDisplay.xsl"/> 

<xsl:template match="/"> 
    <!-- store intermediate form as RTF --> 
    <xsl:variable name="newXmlData"> 
    <xsl:apply-templates mode="filter"/> 
    </xsl:variable> 

    <!-- Now apply templates (with xslt-fo) defined in projDisplay.xsl with  --> 
    <!-- the root template as <xsl:template match="projectteam" mode="display"> --> 
    <!-- to the above RTF (i.e. after the original XML has be convertedr)  --> 
    <xsl:apply-templates select="exslt:node-set($newXmlData)/projectteam" mode="display"/> 

</xsl:template> 

<!-- use identity templates to copy and modify original XML --> 
<xsl:template match="@*|node()" mode="filter"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()" mode="filter"/> 
    </xsl:copy> 
    </xsl:template> 

<!-- replace element 'role' with a new element - role name (i.e. dev or qa) --> 
<!-- and set its value as 'hrs            --> 
<xsl:template match="member/role" mode="filter"> 
    <xsl:element name="{.}"> <xsl:value-of select="../hrs"/> </xsl:element> 
</xsl:template> 

<!-- eliminate element 'hrs' --> 
<xsl:template match="hrs" mode="filter"/> 

</xsl:stylesheet> 
2

Qu'en est-:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format" 
    xmlns:exslt="http://exslt.org/common" 
    exclude-result-prefixes="exslt" 
> 

    <xsl:import href="projDisplay.xsl"/> 

    <xsl:template match="/"> 
    <!-- store intermediary format as a RTF --> 
    <xsl:variable name="newXmlData"> 
     <xsl:apply-templates /> 
    </xsl:variable> 
    <!-- now we can the apply imported rules --> 
    <xsl:apply-templates 
     select="exslt:node-set($newXmlData)/projectteam" 
     mode="import" 
    /> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

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

    <xsl:template match="member/*" /> 

    <xsl:template match="projectteam" mode="import"> 
    <fo:root> 
     <xsl:apply-imports /> 
    </fo:root> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Non, cela n'a pas fonctionné. btw, xsl: apply-imports n'accepte pas les options select et mode. Ensuite, j'ai essayé de remplacer apply-imports par apply-templates, et cela n'a pas fonctionné non plus. FOP se plaint de l'objet de mise en forme inconnu pour chacun des éléments de la feuille de style. Mais, il se plaint de "dev" et "qa" avec le reste des éléments, donc la traduction est arrivée ... Alors, qu'est-ce qui ne va pas ici? –

+0

Non, ne fonctionne pas non plus; J'obtiens cette erreur: xsl: apply-imports non autorisé dans un xsl: for-each –