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 ?
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.
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)
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
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)