Processeur xslt pour fichier volumineux

Bonjour tout le monde,

J’ai fait pas mal de recherche et je n’ai strictement rien trouvé de satisfaisant. Donc je me dis que j’aurais peut être plus de chance en demandant.
Alors c’est pas tout à fait du web dev mais si je parle de xsl dans la partie seg fault, je vais me faire incendier B)

J’ai des fichiers xml (très ?) volumineux, d’environ 150 Mo, que je doit transformer en de jolis fichiers plats d’où le xsl. Le principal problème est que je manque de mémoire pour traiter un tel fichier sans utiliser de façon abusive le swap.
Bon, autant dire que pour ce genre de chose, on peut oublier xsltproc.
Actuellement, le processeur utilisé est Sablotron en ligne de commande (sabcmd) et c’est le plus efficace que j’ai vu. Mais avec 1 Go de RAM et 2 Go de swap sur la machine, il arrive que le process se fasse tout de même ramasser par le oomk …

Est-ce que vous connaitriez, par hasard, un processeur xsl en ligne de commande, dans le même style que Sablotron, mais optimisé (ou au moins un peu plus efficace) pour les très très gros fichiers ?

Merci.

Salut,

Alors pour autant que je sache, utiliser XSL, ça signifie employer le modèle DOM et donc charger tout le doc en mémoire, avec un super bonus de taille… En gros, pour un fichier de 150Mo, je pense (mais je peux me tromper) que XSLT n’est pas la bonne solution.

Il vaut mieux utiliser un parser SAX, qui traite le document séquentiellement, sans charger tout en mémoire. Le hic, c’est qu’il faut savoir programmer pour le faire. Tu ne peux vraiment pas découper ton fichier avant le traitement? Est-ce que les modification de structure du fichier sont complexes au point d’avoir besoin de XSLT?

Si tu connais Perl, il y a toujours moyen de combiner SAX et DOM à l’aide de l’API xmltwig. Si tu ne connais pas Perl, oublie cette dernière phrase.

voilà… j’espère ne pas avoir pourri ta soirée.


mzi

j’avais commencé à écrire une réponse au boulot, mais j’avais peur de me faire incendire parce que “je proposais pas un modèle XSLT, et qe c’est ce qu’on me demande”, mais comme quelqu’un a proposé un parser SAX, je ne fais qu’approuver… c’est un peu chiant dans la mesure ou tu peux pas aller en arrière, d’ou l’idée de diviser ton gros fichier XML en plein de petit fichiers,et après, tu peux passer un coup de parser DOM, si vraiment t’en as besoin…

Java te fourni un parser SAX pas trop dur à utiliser

Alors mon principal problème vient justement du fait qu’il est assez dur de découper le fichier.

Explication du modèle :
En java, je vais chercher mes données en base et je construit un joli xml qui les contients de manière logique, donc non spécifique au fichier plat que je suis sensé généré. D’autant que le modèle est prévu pour être flexible et le xml utilisable dans d’autres cas. Donc la génération du xml doit faire completement abstraction de son utilité dans le cas qui m’interresse.

Je me retrouve donc avec un xml qui contient mes données, pas du tout préparées pour ce que je veux en faire. Si l’on voulait se referer à un modèle, le MVC ferait parfaitement l’affaire. Les couches données et metier correspondant au Java et la couche présentation étant assurée par le xsl. Chaque couche devant ignorer quasi-completement le fonctionnement de son voisin.

En ce qui concerne le perl, j’y pense … mais redevelopper un parser n’est pas le but, sinon, autant générer directement un fichier plat au lieu de passer par un xml B)

Jusqu’à maintenant, sabcmd était parfait pour ça :

  • Extraction des données en java
  • Génération du xml en java
  • Transformation xsl via sabcmd en ligne de commande

Le tout parfaitement orchestré en ant (légérement détourné de son utilité première).

Mon but est de ne toucher QUE à la partie “Transformation” avec un minimum de dev, voir aucun … donc utiliser le même xsl, le même xml … mais changer le parser pour qu’il gére un peu mieux la mémoire et le swap, par exemple en générant son propre fichier de swap, en cas de besoin, pour eviter de charger le tout en mémoire. Mais je n’ai pas une très bonne vision du bousin, donc je ne sais même pas si ce que je raconte à un sens B)

Désolé, mais avec un fichier de cette taille, il va falloir travailler un peu… Je veux dire: faire un minimum de dev…

À quoi ressemble le xml (petit snip, plz)?

les fichiers XML dont je parlais ont été générés exactement pour la même chose : on avait une base (grosse) et ont devait faire un portage vers une autre web app. donc ce qu’on a fait, c’est de séparer la génération de chaque table en différents fichiers XML + properties. Je m’explique : si t’as tout plein d’éléments dans une table A qui référencent des objets d’une table B, t’extraits tous les objets de A dans un gros fichier (ou plusieurs, si tu dois les trier en partie assez conséquentes), et tu références un fichier qui va être en fait l’ID de l’objet de B qui est référencé, et chaque objet B référencé va être un fichier séparé. faut bien choisir les tables A et B, pour que ca soit parsable, c’est un peu crade (t’as 100 000 fichiers de moins de 1ko), c’est un peu lent à récupérer (parce que faut ouvrir un nouveau fichier pour chaque objet de B), mais globalement ca marche pas trop mal.
Et si t’as certains truc que tu dois garder (style une correspondance ancien ID<->nouveau ID ou savoir par qui est pointé tel objet), t’utilises des fichiers properties

J’ai pas trop compris ton problème …
Si ton fichier xml généré ne te plait pas pourquoi tu ne changes pas ton fichier xslt pour avoir ce que tu veux ?

sinon
UN bout de code en java comme ça suffit pas ?

[code]import javax.xml.transform.;
import javax.xml.transform.stream.
;

/**

  • Pour tester un fichier .xsl en ligne de commande.
  • Le résultat de la transformation de truc.xml
  • est affiché sur la sortie standard.
  • Usage : java TestXSL machin.xsl truc.xml.
    */
    public class TestXSLT {
    public static void main(String[] args)
    throws TransformerConfigurationException, TransformerException {
    String styleSheet = args[0];
    String xmlSource = args[1];
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer t = tf.newTransformer(new StreamSource(styleSheet));
    t.transform(new StreamSource(xmlSource),
    new StreamResult(System.out));
    }
    }[/code]

Sinon tu peut essayer Xalan aussi

Tu devrais jeter un coup d’oeil au JDK 6 : http://javaboutique.internet.com/tutorials/staxxsl/
Ca permet de faire du xslt avec un parseur Stax (c’est comme sax sauf que ca permet de streamer le fichier XML et donc de réduire la consommation mémoire, je pense que c’est exactement ce qu’il te faut !)

C’est le premier lien que j’ai trouvé avec xslt + stax dans google, il y a peut être d’autres implems (mais celle du jdk est déjà bien je pense)