IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Format d'échange (XML, JSON...) Java Discussion :

Effectuer une transformation XSLT qui se trouve dans un jar et qui utilise un XML annexe en dehors de ce jar. [XSLT]


Sujet :

Format d'échange (XML, JSON...) Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 61
    Par défaut Effectuer une transformation XSLT qui se trouve dans un jar et qui utilise un XML annexe en dehors de ce jar.
    Bonjour,


    Le fichier XSLT utilisé se trouve comme ressource dans le JAR.
    Le programme java crée un fichier XML temporaire utilisé par la transformation XSLT, puis il appelle cette transformation XSLT.
    C'est le programme java qui envoie le chemin du fichier annexe XML (en tant que paramètre) à la transformation XSLT.

    Cela fonctionne très bien dans Eclipse... seulement, dès que tout est placé dans le jar, ça ne fonctionne plus: la transformation XSLT ne trouve pas le fichier XML annexe.
    Pourtant, le fichier XML annexe est bien créé et c'est le bon chemin qui est envoyé comme paramètre à la transformation XSLT.

    Quelqu'un aurait-il une idée de solution?


    Un peu de code pour ponctuer tout ça!

    Appel à la transformation dans java ( javax.xml.transform), avec le xslt qui est utilisé à partir du jar.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    URL xsltLocation = MyClass.class.getResource(XSLT_FILE);
    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer(new StreamSource(xsltLocation.toURI().toString()));
     
    transformer.setParameter("xmlreport", TEMP_XML_REPORT);
     
    ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
     
    transformer.transform(new StreamSource(new File(fileName)), new StreamResult(bytearrayoutputstream));

    Utilisation du fichier XML créé au préalable lors de la transformation XSLT:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ...
    <xsl:param name="xmlreport"/>
    ...
    <xsl:if test="document($xmlreport)//validation = 'OK'">
       ...plein de trucs chouettes...
    </xsl:if>
    ...

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Par défaut
    Tu peux peut être implementer un URIResolver sur l'instance de URIResolver pour bien controler ce qui se passe.
    http://java.sun.com/j2se/1.4.2/docs/...URIResolver%29

    Regarde aussi quelle est la "working directory" dans chacun des cas.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 61
    Par défaut
    Merci du conseil pour me débloquer. J'avoue que je ne suis pas très familier avec ce genre de fonctions, sa description ne m'avait pas vraiment interpelé...

    Après plusieurs versions, j'en suis arrivé dans mon cas à réduire le URIResolver au plus strict minimum. Vu que tout était déjà "prêt", il suffit ici de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public class URIResolverAnnex implements URIResolver {    
        public Source resolve(String href, String base) {
            return new StreamSource(new File(href));
        }
    }
    en utilisant bien sûr cet URIResolver pour la transformation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
    transformer.setURIResolver(new URIResolverAnnex());
    ...
    -> la transformation xslt fera bien appel au fichier référencé qui se trouve hors du jar.

    Vu que c'est mon premier URIResolver (et vu que j'ai du mal à trouver de la doc simple sur le sujet), si quelqu'un voit à commentaire à faire sur cette implémentation, je suis prêt à encaisser les critiques avec le sourire pour pouvoir l'améliorer. ; )


    Encore merci!

    PS: Je me suis demandé si je n'aurais pas mieux fait d'utiliser l'URIResolver pour "virtualiser" le fichier annexe utilisé par la transformation XSLT. C'est à dire: générer le contenu du fichier et l'envoyer directement à la transformation en tant que InputStream via l'URIResolver, sans pour autant créer physiquement le fichier temporaire. Mais je n'y suis pas encore arrivé. Au moins ça fonctionne, je suis déjà content.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Par défaut
    Hello,
    C'est très bien comme ça ton URIResolver.
    En général, tant qu'on souhaite pas le ré-utiliser et qu'il est simple, on passe par une classe anonyme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    transformer.setURIResolver(new URIResolver(){    
        public Source resolve(String href, String base) {
            return new StreamSource(new File(href));
        }
    });
    Et en effet, tu pourrais passer un InputStream ou un Reader au StreamSource pour ne pas stoker de fichier intermédiaire si c'est ton besoin.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 61
    Par défaut
    Merci pour l'astuce! Je n'ai pas l'habitude de déclarer des classes comme proposé... mais c'est vrai qu'ici, c'est tout à fait approprié, et ça ne gâche aucunement la lisibilité (au contraire).

    Si j'ai le temps (et l'envie), je ré-essaierai en injectant le fichier sans le créer physiquement, et je viendrai mettre une solution ici.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2004
    Messages : 61
    Par défaut
    Pour finir, je me suis penché sur la manière d'éviter de construire physiquement le fichier XML annexe utilisé par la transformation XSLT, ça me semble quand même beaucoup plus propre.

    Petite note avant de commencer:
    Le fichier XML utilisé par la transformation XSLT est lui-même construit à partir d'un fichier de référence. Comme on peut le voir ci-dessous, j'ai fait le choix de d'inclure l'emplacement de fichier de référence dans le paramètre injecté dans le xslt. Ce paramètre est ensuite utilisé par document() lors de la transformation. Ainsi, le nom de fichier de référence se trouve dans le "href" du URIResolver, qui peut ainsi l'utiliser pour construire le fameux fichier XML annexe virtuel.

    Une autre façon de faire aurait été de fournir le nom de fichier de référence au constructeur du URIResolver, ce qui serait peut-être plus propre.
    Je vous avoue que j'ai du mal à trancher... Si par hasard un bon en architecture passe voir ce sujet "résolu" et prend la peine de le lire (on ne sait jamais...), je serais curieux d'avoir son avis.



    Au final, c'est très simple. (Comme souvent quand on sait comment!)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    transformer.setParameter("xmlreport", TEMP_XML_REPORT + "-" + fileName);
     
    transformer.setURIResolver(new URIResolver() {
         public Source resolve(String href, String base) {
              String stringXMLReport = getStringReport(href.replaceFirst(TEMP_XML_REPORT + "-", ""));
              return new StreamSource(new ByteArrayInputStream(stringXMLReport.getBytes()));
         } 
    });
    Je précise que getStringReport est une méthode perso qui renvoie un String du fichier XML annexe.
    A noter également que j'ai d'abord essayé avec un new "StringReader(stringXmlReport)" à la place du "ByteArrayInputStream(stringXmlReport.getBytes())". Malheureusement, j'avais des problèmes d'accent, et je ne trouvais vraiment pas comment modifier le charset avec un StringReader.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment effectuer une transformation XSLT avec Delphi ?
    Par Raylemon dans le forum Télécharger
    Réponses: 0
    Dernier message: 10/01/2012, 16h21
  2. Réponses: 0
    Dernier message: 10/01/2012, 16h20
  3. Réponses: 0
    Dernier message: 10/01/2012, 16h19
  4. Réponses: 0
    Dernier message: 10/01/2012, 16h18
  5. [XL-2007] Trouver un bout de code dans des fichiers Excel qui se trouve dans un répertoire
    Par Paloma dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 08/11/2010, 16h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo