12 votes

Analyse syntaxique de gros documents XML en JAVA

J'ai le problème suivant :

J'ai un fichier XML (d'environ 1 Go), et je dois l'itérer de haut en bas (c'est-à-dire non séquentiel, l'un après l'autre) afin d'obtenir les données requises et d'effectuer certaines opérations sur celles-ci. Au départ, j'ai utilisé le paquet Java DOM, mais évidemment, lors de l'analyse du fichier XML, la JVM a atteint son espace maximum dans le tas et s'est arrêtée.

Afin de surmonter ce problème, l'une des solutions que j'ai trouvées a été de trouver un autre analyseur qui itère chaque élément du XML, puis de stocker son contenu dans une base de données SQLite temporaire sur mon disque dur. Ainsi, de cette façon, le tas de la JVM n'est pas dépassé, et une fois que toutes les données sont remplies, j'ignore le fichier XML et continue mes opérations sur la base de données SQLite temporaire.

Existe-t-il un autre moyen de résoudre mon problème ?

13voto

SAX (Simple API for XML) vous aidera ici.

Contrairement à l'analyseur DOM, l'analyseur SAX ne crée pas de représentation en mémoire du document XML. du document XML et est donc plus rapide et utilise moins de mémoire. Au lieu de cela, l'analyseur syntaxique SAX informe les clients de la structure du document XML en invoquant des rappels, c'est-à-dire en invoquant des fonctions de rappel. en invoquant des callbacks, c'est-à-dire en invoquant des méthodes sur un fichier de type org.xml.sax.helpers.DefaultHandler fournie à l'analyseur syntaxique.

Voici un exemple de mise en œuvre :

SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
DefaultHandler handler = new MyHandler();
parser.parse("file.xml", handler);

Où dans MyHandler vous définissez les actions à entreprendre lorsque des événements tels que le début/la fin d'un document/élément sont générés.

class MyHandler extends DefaultHandler {

    @Override
    public void startDocument() throws SAXException {
    }

    @Override
    public void endDocument() throws SAXException {
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
    }

    // To take specific actions for each chunk of character data (such as
    // adding the data to a node or buffer, or printing it to a file).
    @Override
    public void characters(char ch[], int start, int length)
            throws SAXException {
    }

}

3voto

GaborSch Points 6587

Si vous ne voulez pas être lié par la directive limites de mémoire Je vous recommande certainement d'utiliser votre approche actuelle et de tout stocker dans une base de données.

L'analyse syntaxique du fichier XML doit être effectuée par un module SAX parser comme tout le monde l'a recommandé (y compris moi). De cette façon, vous pouvez créer un objet à la fois, et vous pouvez immédiatement le persister dans la base de données.

Pour le post-traitement (résolution des références croisées), vous pouvez utiliser SELECT de la base de données, créer des clés primaires, des index, etc. Vous pouvez également utiliser un ORM (Eclipselink, Hibernate) si vous vous sentez à l'aise avec cela.

En fait, je ne recommande pas vraiment SQLite, il est plus facile de mettre en place un serveur MySQL, et d'y stocker les données. Plus tard, vous pourrez même réutiliser les données XML (si vous ne les supprimez pas).

1voto

Michael Kay Points 52194

Si vous souhaitez utiliser une approche de plus haut niveau que SAX, qui peut être très délicate à programmer, vous pouvez envisager de diffuser des transformations XSLT à l'aide d'une version récente de Saxon-EE. Cependant, vous êtes resté trop vague sur le traitement précis que vous effectuez pour savoir si cela fonctionnera dans votre cas particulier.

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