Comme le titre le dit, j'ai un énorme fichier XML (GBS) et je voudrais le transformer en un peu plus petit qui ne conserve que quelques-uns des éléments . L'étape 1 est facile avec sax et impossible pour Dom-anal-anal. Alors quoi? - Y a-t-il un moyen creux de combiner sax et dom-anal d'analyseur pour faire la tâche? P> p>
Mon analyseur devrait faire ce qui suit:
1. Analyser le fichier jusqu'à ce qu'un élément pertinent commence.
2. Copiez l'élément pertinent complet (avec enfants) dans le fichier de sortie. Aller à 1. p>
L'étape 2 est agaçante avec saxo, mais facile avec le DOM-Parser ou XSLT. P>
7 Réponses :
Stax semblerait être une solution évidente: c'est un analyseur de tir plutôt que le "Push" de sax ou le "tampon tout ce qui est" "approche de dom. Je ne peux pas dire que je l'ai utilisé cependant. Un "Tutoriel Stax" La recherche peut être utile :) p >
+1 Stax est plus facile à utiliser que Sax si vous n'avez pas été exposé à la gestion des fichiers XML auparavant. En outre, il permet également d'écrire XML (contrairement à saxo).
Oui, écrivez simplement un gestionnaire de contenu SAX, et lorsqu'il rencontre un certain élément, vous construisez un arbre DOM sur cet élément. Je l'ai fait avec de très gros fichiers et ça fonctionne très bien. P>
C'est en fait très facile: dès que vous rencontrez le début de l'élément souhaité, vous définissez un drapeau dans votre gestionnaire de contenu et à partir de là, vous transmettez tout au constructeur DOM. Lorsque vous rencontrez la fin de l'élément, vous définissez le drapeau sur FALSE et écrivez le résultat. P>
(Pour des cas plus complexes avec des éléments imbriqués du même nom d'élément, vous devez créer une pile ou un compteur, mais c'est toujours assez facile à faire.) P>
Jetez un coup d'œil à Stax , cela pourrait être ce dont vous avez besoin. Il y a une bonne introduction sur Développeur IBM fonctionne . < / p>
Vous pouvez le faire assez facilement avec un XMLEVENTReader CODE> et plusieurs
xmleventwriter code> S du package Javax.xml.stream. P>
Puisque vous parlez de GB, je préférerais hiérarchiser l'utilisation de la mémoire dans la considération. SAX a besoin d'environ 2 fois la mémoire que le document BIG est, tandis que DOM en a besoin pour être au moins em> 5 fois. Donc, si votre fichier XML est de 1 Go BIG, alors DOM nécessiterait un minimum de 5 Go de mémoire libre. Ce n'est plus drôle. SO SAX (ou une variante sur celle-ci, comme Stax) est la meilleure option ici. P>
Si vous souhaitez l'approche la plus efficace de la mémoire, regardez VTD-XML . Il ne nécessite que un peu em> plus de mémoire que le fichier grand est. P>
Bon point, la mémoire est absolument cruciale ici. BTW, SAX n'a même pas nécessairement besoin de deux fois la taille du document - car il s'agit d'une API en streaming, vous pouvez constamment des ordures collecter des parties précédentes du document, dès que vous n'en avez plus besoin.
Vrai, mais cela dépend des exigences fonctionnelles. Il pourrait par exemple avoir besoin d'avoir la totalité de XML en mémoire avant de pouvoir rassembler les informations souhaitées.
Pour un tel document XML, quelque chose avec une architecture en streaming, comme Omnimark serait idéal.
Il n'aurait pas besoin d'être complexe non plus. Un script omnimark comme ce qui est ci-dessous pourrait vous donner ce dont vous avez besoin: P>
process submit #main-input macro upto (arg string) is ((lookahead not string) any)* macro-end find (("<keep") upto ("</keep>") "</keep>")=>keep output keep find any
J'ai fait de bonnes expériences avec STX ( Transformations de streaming pour XML forte>). Fondamentalement, il s'agit d'une version streamée de XSLT, bien adaptée à l'analyse d'énormes quantités de données avec une empreinte de mémoire minimale. Il a une implémentation dans Java nommée JOOST . Il devrait être facile de trouver une transformation STX qui ignore tous les éléments jusqu'à ce que l'élément correspond à un XPath donné, copie cet élément et tous ses enfants (à l'aide d'un modèle d'identité dans un groupe de gabarits) et continue d'ignorer les éléments jusqu'à la correspondance suivante. P> Mise à jour forte> p> J'ai piraté une transformation STX qui fait ce que je comprends que vous voulez. Il dépend surtout des fonctionnalités STX uniquement telles que des groupes de modèles et des modèles par défaut configurables. P> <?xml version="1.0" encoding="UTF-8"?>
<child attribute="value1">
text1<b>bold</b>
</child><child attribute="value2">
text2
<x:childX xmlns:x="http://x.example.com/x">
<!-- comment -->
yet more<b i="i" x:i="x-i" />
</x:childX>
</child>
ça a l'air bien. Puis-je simplement écrire une feuille de styles xslt et ensuite l'exécuter avec STX?
Non, ce n'est pas possible. Tandis que XSLT utilise des modes pour distinguer les modèles pour la même correspondance dans différentes situations (mode de saut V. Mode Copie, dans votre cas), STX utilise des groupes de modèles. La syntaxe dans les modèles est similaire à XSLT, mais différente en détail. J'ajoute un exemple de transformer à ma réponse.
Notez que, dans le XPath pour correspondre à un modèle, seuls les nœuds que vous pouvez accéder sont le nœud actuel, ses nœuds parents et leurs attributs. Vous ne pouvez pas correspondre à aucun autre nœud précédent ou suivant, en raison de la nature en streaming de la transformation. Si vous avez besoin de ce type de correspondance, vous pouvez définir des variables (qui sont mutables) et les utiliser dans STX: si code> tests. Mais ceci est délicat et ressemble à mettre en œuvre un gestionnaire de contenu dans XML.