10
votes

Lecture d'un énorme fichier XML en utilisant STAX et XPATH

Le fichier d'entrée contient des milliers de transactions au format XML qui correspond à environ 10 Go de taille. L'exigence est de choisir chaque transaction XML sur la base de l'entrée de l'utilisateur et de l'envoyer au système de traitement.

la teneur en échantillonnage du fichier xxx

L'utilisateur (technique) devrait donner le nom de la balise d'entrée comme .

Nous aimerions fournir cette solution être plus générique. Le contenu du fichier peut être différent et les utilisateurs peuvent donner une expression xpath comme " // transactions / txn " pour choisir des transactions individuelles.

il y a peu de choses techniques que nous avons considérer ici

  • Le fichier peut être dans un emplacement partagé ou FTP
  • Étant donné que la taille du fichier est énorme, nous ne pouvons pas charger le fichier entier dans JVM

    pouvons-nous utiliser Stax Parser pour ce scénario? Il doit adopter une expression XPath comme une transaction d'entrée et de sélection / sélection de la transaction XML.

    à la recherche de suggestions. Merci d'avance.


1 commentaires

Ma recommandation est d'utiliser VTD-XML étendu dans le mode MEM Map et 64 bits JVM


7 Réponses :


13
votes

Stax et XPath sont des choses très différentes. Stax vous permet d'analyser un document XML en streaming uniquement dans une direction avant. XPath permet d'analyser dans les deux sens. Stax est un analyseur XML en streaming très rapide, mais si vous voulez XPath, Java a une bibliothèque distincte pour cela.

Jetez un coup d'œil à cette question pour une discussion très similaire: Y a-t-il un processeur XPATH pour le modèle SAX?


2 commentaires

Si vous allez me désactiver, laissez un commentaire s'il vous plaît. De cette façon, tout le monde apprend!


Down votant parce que votre déclaration "Stax and XPath est des choses très différentes" n'est pas correcte. XPath (au moins le sous-ensemble de celui-ci) peut toujours être implémenté dans le modèle STAX (modèle de tirage). Sa mise en œuvre dans c # msdn.microsoft.com/en-us/library/ms950778. Aspx



0
votes

Transformations de streaming pour XML (STX) pourrait être ce dont vous avez besoin.


0 commentaires

0
votes

Avez-vous besoin de le traiter rapidement ou vous avez besoin de recherches rapides dans les données? Ces exigences ont besoin d'une approche différente.

Pour la lecture rapide de l'ensemble des données Stax ira bien.

Si vous avez besoin de recherches rapides que vous n'auriez besoin de le charger sur une base de données, Berkeley DB XML E.G.


0 commentaires

1
votes

C'est certainement un cas d'utilisation pour XProc avec une mise en oeuvre de traitement en streaming et parallèle comme QuixProc ( http: // code .google.com / p / QuixProc )

Dans cette situation, vous devrez utiliser P>

  <p:wrap-sequence wrapper="transactions"/>


0 commentaires

2
votes

Nous analysons régulièrement des fichiers XML complexes 1GB + à l'aide d'un analyseur SAX qui fait exactement ce que vous avez décrit: il extrait des arbres doms partiels qui peuvent être correctement interrogés en utilisant XPath.

j'ai blogué à propos de ici - Il utilise un sax non un analyseur Stax, mais peut valoir un coup d'œil.


0 commentaires

16
votes

Si la performance est un facteur important et / ou la taille du document est grande (qui semble être le cas ici), la différence entre un analyseur d'événement (comme saxe ou stax) et la mise en œuvre de Java XPath natif est que Ce dernier établit un document DOM W3C avant d'évaluer l'expression XPath. [Il est intéressant de noter que toutes les implémentations de modèle d'objet de document Java comme le DOM ou Axiom utilisent un processeur d'événement (comme SAX ou Stax) pour construire la représentation en mémoire, donc si vous pouvez jamais obtenir avec uniquement le processeur d'événement que vous êtes Enregistrant à la fois la mémoire et le temps nécessaire pour construire un DOM.]

Comme je l'ai mentionné, la mise en œuvre de XPath dans le JDK fonctionne sur un document W3C DOM. Vous pouvez le voir dans l'implémentation de code source JDK JAVA JDK en consultant com.sun.org.apache.xpath.internal.jaxp.xpathimpl , où avant la méthode d'évaluation () appelée l'analyseur doit Premièrement analysez la source: xxx

Après cela, votre 10 Go de XML sera représenté en mémoire (plus quel que soit le versh) - probablement pas ce que vous voulez. Bien que vous puissiez vouloir une solution plus "générique", votre exemple XPath et votre balisage XML semblent relativement simples, il ne semble donc pas y avoir une très forte justification d'un XPath (sauf peut-être peut-être l'élégance de programmation ). Il en va de même pour la suggestion XProc: cela construirait également un DOM. Si vous avez vraiment besoin d'un DOM, vous pouvez utiliser AXIOM plutôt que le W3C DOM. Axiom a une API beaucoup plus amicale et construit son DOM sur Stax, il est donc rapide et utilise Jaxen pour sa mise en œuvre de XPath. Jaxen nécessite certains type de DOM (W3C DOM, DOM4J ou JDOM). Ce sera vrai de toutes les implémentations XPath, donc si vous n'avez pas vraiment besoin de xpath coller avec juste l'analyseur d'événements serait recommandé.

SAX est l'ancienne API en streaming, avec Stax Newer, et une bonne affaire plus rapide. Soit en utilisant la mise en oeuvre de Stax JDK natif ( javax.xml.stream ) ou le woodstox mise en œuvre de stax (qui est De manière significative, dans mon expérience), je vous recommanderais de créer un filtre d'événements XML qui correspond à un nom de type d'élément (pour capturer votre éléments). Cela créera de petites rafales d'événements (élément, attributs, texte) pouvant être vérifiés pour vos valeurs utilisateur correspondantes. Lors d'une correspondance appropriée, vous pouvez tirer les informations nécessaires des événements ou tuyer les événements délimités pour créer un mini-dom à partir de leur part si vous avez trouvé le résultat était plus facile à naviguer. Mais cela sonne comme ça pourrait être surchargé si le balisage est simple.

Ce serait probablement l'approche la plus simple et la plus rapide possible et éviter la mémoire de la mémoire de la construction d'un DOM. Si vous avez passé les noms de l'élément et l'attribut au filtre (de sorte que votre algorithme de correspondance soit configurable), vous pouvez le rendre relativement générique.


3 commentaires

Avez-vous entendu parler de VTD-XML?


Pas avant votre commentaire, non je n'avais pas. J'ai téléchargé la distribution et je serai heureux de l'essayer. Celui-ci s'effectue telle que réclamée, j'envisagerais de l'utiliser dans des environnements de production, mais l'attelage que je vois incline me demander (puisque vous êtes son auteur) si vous êtes prêt à libérer VTD-XML sous un LGPL ou Apache Licence? Nous ne pouvons tout simplement pas utiliser GPL dans notre environnement. Merci pour la pointe dans tous les cas.


@Ichirofurusato - grand commentaire.



1
votes

Une solution amusante pour traiter d'énormes fichiers XML> 10 Go.

  1. Utilisez ANTLR pour créer des compensations d'octets pour les parties d'intérêt. Cela sauvera une certaine mémoire par rapport à une approche basée sur DOM.
  2. Utilisez JAXB pour lire des pièces de la position d'octet

    Trouver des détails à l'exemple de Wikipedia Dumps (17 Go) dans cette réponse https://stackoverflow.com/a/43367629/ 1485527


0 commentaires