29 votes

Quel est le processeur XSLT en continu basé sur Java le plus efficace ?

J'ai un très gros fichier XML que je dois transformer en un autre fichier XML, et j'aimerais le faire avec XSLT. Je m'intéresse davantage à l'optimisation de la mémoire qu'à l'optimisation de la vitesse (même si la vitesse est aussi une bonne chose !).

Quel processeur XSLT basé sur Java recommanderiez-vous pour cette tâche ?

Recommanderiez-vous une autre façon de procéder (non-XSLT ?, non-Java ?), et si oui, pourquoi ?

Les fichiers XML en question sont très volumineux, mais pas très profonds - avec des millions de rangées (éléments), mais seulement environ 3 niveaux de profondeur.

34voto

Dimitre Novatchev Points 147842

Actuellement, il n'y a que trois XSLT 2.0 processeurs connus et d'eux Saxon 9.x est probablement le plus efficace (du moins d'après mon expérience) à la fois en termes de vitesse et d'utilisation de la mémoire. Saxon-SA (la version de Saxon tenant compte des schémas, non gratuite comme la version B (de base)) possède des extensions spéciales pour le traitement en continu.

A partir des différents XSLT 1.0 processeurs, .NET XslCompiledTransform (basé sur C#, pas Java !) semble être le champion.

Dans le monde basé sur Java des processeurs XSLT 1.0 Saxon 6.x encore une fois, c'est plutôt bien.

UPDATE :

Aujourd'hui, plus de trois ans après la réponse initiale à cette question, il n'y a aucune preuve que la différence d'efficacité entre les processeurs XSLT mentionnés ait changé.

Quant au streaming :

  1. Un document XML comportant des "millions de nœuds" peut très bien être traité même sans aucun streaming. . J'ai réalisé une expérience dans laquelle Saxom 9.1.07 a traité un document XML qui contient environ un million d'éléments de 3e niveau avec des valeurs entières. La transformation calcule simplement leur somme. Le temps total de la transformation sur mon ordinateur est inférieur à 1,5 secondes. La mémoire utilisée était de 500MB -- quelque chose que les PC pouvaient avoir même il y a 10 ans,

Voici les messages d'information de Saxon qui donnent des détails sur la transformation :

Saxon 9.1.0.7J from Saxonica
Java version 1.6.0_17
Stylesheet compilation time: 190 milliseconds
Processing file:/C:\temp\delete\MRowst.xml
Building tree for file:/C:\temp\delete\MRowst.xml using class net.sf.saxon.tinytree.TinyBuilder
Tree built in 1053 milliseconds
Tree size: 3075004 nodes, 1800000 characters, 0 attributes
Loading net.sf.saxon.event.MessageEmitter
Execution time: 1448 milliseconds
Memory used: 506661648
NamePool contents: 14 entries in 14 chains. 6 prefixes, 6 URIs
  1. Saxon 9.4 a a Fonction d'extension saxon:stream() qui peut être utilisé pour le traitement d'énormes documents XML.

Voici un extrait de la documentation :

Il y a essentiellement deux façons de faire du streaming en Saxon :

Streaming en mode rafale : avec cette approche, la transformation d'une fichier de grande taille est décomposée en une séquence de transformations de petits morceaux du fichier. Chaque morceau est lu à partir de l'entrée, transformé en un petit arbre en mémoire, transformé et écrit sur la sortie. en un petit arbre en mémoire, transformé et écrit dans le fichier de sortie. fichier.

Cette approche fonctionne bien pour les fichiers dont la structure est assez plate, par exemple un fichier journal contenant des millions d'enregistrements de journal, où le traitement de chaque enregistrement est indépendant de ceux qui l'ont précédé. précédents.

Une variante de cette technique utilise la nouvelle instruction XSLT 3.0 xsl:iterate pour itérer sur les enregistrements, à la place de xsl:for-each. Cela permet de conserver les données de travail au fur et à mesure du traitement des enregistrements. traitement des enregistrements : il est ainsi possible, par exemple, d'éditer des totaux ou des statistiques. ou des moyennes à la fin de l'exécution, ou de faire en sorte que le traitement d'une d'un enregistrement en fonction de ce qui le précède dans le fichier. L'instruction xsl:iterate permet également de sortir prématurément de la boucle, ce qui rend ce qui permet à une transformation de traiter des données depuis le début d'un grand fichier sans lire le fichier entier.

La diffusion en continu en mode rafale est disponible à la fois dans XSLT et XQuery, mais il y a mais il n'y a pas d'équivalent en XQuery à la construction xsl:iterate.

Modèles de flux : cette approche suit le modèle traditionnel de traitement XSLT qui consiste à effectuer une descente récursive de la hiérarchie XML d'entrée en faisant correspondre des modèles de flux à des modèles de flux. d'entrée en faisant correspondre les règles des modèles aux nœuds à chaque niveau, mais mais elle le fait un élément à la fois, sans construire l'arbre en mémoire.

Chaque modèle appartient à un mode (peut-être le mode par défaut, sans nom), et le streaming est une propriété du mode qui peut être spécifiée en utilisant la nouvelle déclaration xsl:mode. Si le mode est déclaré comme étant streamable, alors chaque règle de modèle au sein de ce mode doit obéir aux pour le traitement en continu.

Les règles pour ce qui est autorisé dans le traitement en continu sont assez compliquées, mais le principe essentiel est que la règle du modèle pour un un nœud donné ne peut lire les descendants de ce nœud qu'une seule fois, en dans l'ordre. Il existe d'autres règles imposées par les limitations de l'architecture actuelle de l Saxon : par exemple, bien que le regroupement à l'aide de soit théoriquement cohérent avec une implémentation en flux, il n'est pas actuellement implémenté dans Saxon. Saxon.

  1. XSLT 3.0 aurait la norme fonction de streaming . Toutefois, le document du W3C a toujours le statut de "working draft" et la spécification du streaming est susceptible d'être modifiée dans les versions ultérieures. C'est pourquoi il n'existe aucune mise en œuvre de la spécification actuelle (streaming).

  2. Avertissement : Toutes les transformations ne peuvent pas être effectuées en mode streaming -- quel que soit le processeur XSLT. Un exemple de transformation qu'il n'est pas possible d'effectuer en mode streaming (avec une quantité limitée de RAM) pour des documents volumineux est le tri de leurs éléments (disons par un attribut commun).

9voto

Stephen Denne Points 17031

Vous pourriez envisager STX dont l'implémentation Java est Joost . Comme il est similaire à XSLT, mais qu'il s'agit d'un processeur de flux, il est capable de traiter d'énormes fichiers en utilisant très peu de RAM.

Joost peut être utilisé comme un TransformerFactory standard de javax.xml.transform.

4voto

Peter Štibraný Points 17507

Voir le support Saxon pour le mode streaming. http://www.saxonica.com/html/documentation/sourcedocs/streaming/

Si ce mode de streaming n'est pas pour vous, vous pouvez essayer d'utiliser mode petit arbre de Saxon, qui est optimisé pour une utilisation réduite de la mémoire. (C'est la version par défaut de toute façon)

0voto

Jacek Ambroziak Points 21

Essayer le compilateur optimisant Gregor/XSLT

-1voto

Raghav Mac Points 112

Saxon 9.x est probablement le plus efficace, tant en termes de vitesse que d'utilisation de la mémoire. Saxon-SA dispose d'extensions spéciales pour le traitement en continu. Il n'y a que trois processeurs XSLT 2.0 connus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X