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

XSL/XSLT/XPATH XML Discussion :

enregistrement dans un fichier d'une string XSL-FO


Sujet :

XSL/XSLT/XPATH XML

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de titouille
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    353
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 353
    Par défaut enregistrement dans un fichier d'une string XSL-FO
    Bonjour à tous !!

    Ok, ok... ça va surement paraître trivial pour certains, mais je galère pour enregistrement une chaine XML dans un fichier...

    Via un script PHP, je génère un document xsl-fo qui est ensuite proposé en téléchargement via les "headers".
    J'ai maintenant une application JAVA qui est sensée envoyer une requête à ce script et en récupérer le contenu. Jusqu'ici tout va bien. A l'aide des exemples de la FAQ, j'ai réussi sans difficulté à récupérer le contenu de mon document.

    Mon problème maintenant est de pouvoir l'enregistrer en tant que document xml "valide". Le but étant de passer le contenu à la moulinette FOP, j'aimerai pouvoir enregistrer ce fichier en local avant de le traiter. Malheureusement je n'y arrive pas...

    J'ai d'abord été confronté à différentes erreurs pour finalement arriver à quelque chose qui me semble assez correct, mais au final ça ne me semble pas du tout optimisé et il reste des problèmes...

    Voici tout d'abord mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    	    // create params for the url
    	    String params = URLEncoder.encode("generation", "UTF-8")+
    		    "="+URLEncoder.encode("0", "UTF-8");
    	    params += "&" + URLEncoder.encode("links", "UTF-8")+
    		    "="+URLEncoder.encode("0", "UTF-8");
    	    params += "&" + URLEncoder.encode("generatePDF", "UTF-8")+
    		    "="+URLEncoder.encode("0", "UTF-8");
     
    	    // connection creation
    	    URL url = new URL( "http://localhost/Flex/as3/projects/fasa/build002/generator2" );
    	    URLConnection conn = url.openConnection();
    	    conn.setDoOutput(true);
     
    	    // request
    	    writer = new OutputStreamWriter(conn.getOutputStream());
    	    writer.write( params );
    	    writer.flush();
     
    	    // answer
    	    reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
     
    	    // delete possibly existing file
    	    File f = new File( "test_catalog.fo" );
    	    if( f != null )
    	    {
    		if( f.exists() )
    		    f.delete();
    	    }
     
    	    // get content of document
    	    String ligne;
    	    String document = "";
    	    int index = 0;
    	    while ((ligne = reader.readLine()) != null && index < 1000 ) 
    	    {
    		//System.out.println( ligne );
    		document += ligne + "\n";
    		index++;
    	    }
     
    	    // parse and transform document to save it as XML
    	    Result res = new StreamResult( new PrintStream( new FileOutputStream( "test_catalog.fo" ) ) );
    	    Source src = new StreamSource( document );
    	    TransformerFactory fac = TransformerFactory.newInstance();
    	    Transformer trans = fac.newTransformer();
     
    	    trans.transform( src, res );
    Premièrement, j'ai une boucle qui lit le document ligne après ligne pour l'intégrer dans une variable... Le souci c'est que mon document possède plus de 60'000 lignes... Si je laisse la méthode lire tout le fichier, ça bloque et après plusieurs minutes je n'ai toujours pas de réponse de l'application... J'ai donc limité la lecture aux milles premières lignes pour faire mes tests, mais ça ne règle pas le problème... Ma première question est donc : existe-t-il un moyen plus simple d'obtenir tout le contenu du BufferedReader ? peut-être que je n'utilise pas les bons objets pour arriver à mon but, je ne sais pas...

    Deuxièmement, une fois le document récupéré, je le balance au processus de parsing, et la console me renvoie une erreur toute simple :

    ERREUR : 'no protocol: ...' avec toute ma chaine XML... J'ai cru comprendre que l'erreur fait référence à un DOCTYPE qui serait manquant, mais je n'arrive pas à comprendre le pourquoi du comment... Dans ma balise fo:root je fais bien référence au xmlns http://www.w3.org/1999/XSL/Format...

    Bref, je suis bloqué et j'imagine que c'est pour pas grand chose, mais je ne trouve pas de solutions... Les suggestions sont donc bienvenues


    D'avance merci !!

  2. #2
    Membre extrêmement actif
    Profil pro
    Développeur Java Indépendant
    Inscrit en
    Mai 2007
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java Indépendant

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 333
    Par défaut
    Citation Envoyé par titouille Voir le message
    Premièrement, j'ai une boucle qui lit le document ligne après ligne pour l'intégrer dans une variable... Le souci c'est que mon document possède plus de 60'000 lignes... Si je laisse la méthode lire tout le fichier, ça bloque et après plusieurs minutes je n'ai toujours pas de réponse de l'application... J'ai donc limité la lecture aux milles premières lignes pour faire mes tests, mais ça ne règle pas le problème... Ma première question est donc : existe-t-il un moyen plus simple d'obtenir tout le contenu du BufferedReader ? peut-être que je n'utilise pas les bons objets pour arriver à mon but, je ne sais pas...


    Bonjour

    Pour ce qui est de cette boucle, je pense qu'il faut utiliser un StringBuilder au lieu d'un String quand on incrémente beaucoup de fois une autre chaine à cette chaine.
    Par exemple ça donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    String ligne;
    	    StringBuilder document = new StringBuilder();
    	    int index = 0;
    	    while ((ligne = reader.readLine()) != null && index < 1000 ) 
    	    {
    		//System.out.println( ligne );
    		document.append(ligne + "\n");
    		index++;
    	    }
    Pour ce qui est du problème du mémoire (pas sûr que ce changement règle le problème, y a t'il moyen de parser et d'écrire dans un autre fichier au fur et à mesure que tu lis ta source ?

    Bon courage

  3. #3
    Membre chevronné Avatar de titouille
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    353
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 353
    Par défaut
    Re,

    Merci beaucoup pour ton explication. Il est clair que ça passe bcp mieux avec la classe StringBuilder.
    Je me retrouve par contre toujours confronté au second problème... J'ai testé pas mal de choses, genre parser la chaine de caractères via un DocumentBuilderFactory en tentant de désactiver la validation XML mais le problème persiste... l'erreur a quelque peu changé :

    java.net.MalformedURLException: no protocol: <?xml version='1.0' encoding='UTF-8'?>


    Il semble que ça soit parce que le parser tente de charger une dtd afin de valider le document... j'ai donc essayé des codes du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
     
    	    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    	    dbf.setValidating(false);
    	    DocumentBuilder db = dbf.newDocumentBuilder();
    	    System.out.println( "isValidating : " + db.isValidating() );
    	    Document d = db.parse( document.toString() );
     
    	    DOMSource src = new DOMSource( d );
     
    	    // parse and transform document to save it as XML
    	    Result res = new StreamResult( new PrintStream( new FileOutputStream( "test_catalog.fo" ) ) );
     
    	    TransformerFactory fac = TransformerFactory.newInstance();
     
    	    Transformer trans = fac.newTransformer();
     
    	    trans.transform( src, res );
    Le println me retourne bien "false" pour la validation, mais l'erreur continue de s'afficher... J'ai un peu de peine à comprendre, mais je vais continuer mes investigations sur le web.

    Encore merci, a+

  4. #4
    Membre extrêmement actif
    Profil pro
    Développeur Java Indépendant
    Inscrit en
    Mai 2007
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Java Indépendant

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 333
    Par défaut
    Re-bonjour

    Le constructeur que tu utilise pour créer ton StreamSource est celui-ci :
    public StreamSource(String systemId)

    Construct a StreamSource from a URL.
    En clair il attend une URL et non pas le contenu brut de ce que tu veux parser. Je pense que c'est pour cela que tu obtient l'erreur.

    Je te conseil d'enregistrer les données dans une fichier (plutôt que de tout garder un StringBuilder) au fur et à mesure que tu le lis*, et ensuite utiliser le constructeur :

    StreamSource(File f)
    Construct a StreamSource from a File.

    Bon courage tien nous au courant

    *Ce qui aura pour effet en plus de réduire la consommation de mémoire.

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par titouille Voir le message

    Mon problème maintenant est de pouvoir l'enregistrer en tant que document xml "valide". Le but étant de passer le contenu à la moulinette FOP, j'aimerai pouvoir enregistrer ce fichier en local avant de le traiter. Malheureusement je n'y arrive pas...
    Ton code fait tout sauf "l'enregistrer en local". Alors ou j'ai pas compris ton besoin ou le code suivant suffit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    InputStream is = conn.getInputStream()
    try{
      FileOutputStream fos = new FileOutputStream(.....);
      try {
        byte[] buffer = new byte[16*1024]; // 16k buffer
        int read = 0;
        while ((read=is.read(buffer))!=-1)
           fos.write(buffer,0,read);
      } finally {
        fos.close();
      }
    } finally {
      is.close();
    }
    [/QUOTE]

  6. #6
    Membre chevronné Avatar de titouille
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    353
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 353
    Par défaut
    Re,

    tchize_, le code que tu m'as donné suffisait. Lorsque j'avais tenté de l'enregistrer directement (avec une boucle) je perdais toute l'indentation du fichier. j'avais donc tenté un parsing du xml avant de l'enregistrer pour avoir le même fichier que celui du serveur, mais après coup je me rend compte que je compliquais les choses plutôt que de les simplifier.

    Merci à vous deux pour votre aide et le temps que vous m'avez consacré

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

Discussions similaires

  1. Installer une imprimante pour enregistrer dans un fichier
    Par Ludovic20 dans le forum RedHat / CentOS / Fedora
    Réponses: 1
    Dernier message: 09/12/2011, 18h02
  2. Réponses: 0
    Dernier message: 15/11/2011, 15h42
  3. Réponses: 5
    Dernier message: 23/01/2009, 10h52
  4. Réponses: 2
    Dernier message: 02/09/2008, 14h17
  5. enregistrer dans un fichier avec une appli mdi
    Par ferrari dans le forum C++Builder
    Réponses: 4
    Dernier message: 05/05/2002, 15h17

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