1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2009
    Messages : 176
    Points : 86
    Points
    86

    Par défaut Diviser XML 20 go en petits fichiers selon une balise

    Bonjours à tous

    J'ai un gros fichiers XML ( 20 go environ) contenant notamment des balises <product> </product>, mais il y a plus de 100k de ces produits.
    Je voudrais trouver le moyen le plus rapide pour faire plusieurs petits fichiers contennant par exemple 100 ou 1000 de ces balises.

    J'ai essayé avec Talend, la mémoire explose...

    J'ai trouvé un script python qui n'utilise pas beaucoup de mémoire mais le fait en 3h.

    J'ai également trouvé un script transcrivant ce python en C, je gagne environ 40 min.

    Mais il me faut absolument trouver une solution pour spliter correctement ce gros XML.
    Je suis en train de voir avec perl, mais je ne suis pas bon du tout.

    Vous avez des idées ?
    Merci

  2. #2
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2009
    Messages : 176
    Points : 86
    Points
    86

    Par défaut

    Pour me répondre un peu à moi-même et aux prochains qui passeraient par là, voici un script ruby qui fait le job en une 15aine de minutes.

    Code Ruby : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    require 'xml'
     
    XML_FILE = './exported_0.xml'
     
    # A special file class that we'll write its output in
    # successive files with the same number of items in it
    # (except for the last one which size may vary)
    class SplitFile
      def initialize(template_name, items_per_file)
        @template_name = template_name
        @items_per_file = items_per_file
        @item_count = 0
        @file_index = 0
        @fh = open()
      end
     
      def write(content)
        @fh.write(content)
        @fh.write("\n")
        @item_count += 1
        if @item_count == @items_per_file
          self.close()
          self.open()
        end
      end
     
      def open
        exit if @file_index == 3
        @file_index += 1
        @fh = File.open(self.batch_name(), 'w')
      end
     
      def close
        @fh.close
        @item_count = 0
      end
     
      def batch_name
        @template_name % @file_index
      end
    end
     
    # XML Processor to split the Product records into
    # smaller XML chunks
    class XMLSplitProcessor
     
      def initialize(xml_sourcefile, split_filename_template)
        @split_filename_template = split_filename_template
        @file_handle = SplitFile.new(split_filename_template, 1000)
        @reader = XML::Reader.file(xml_sourcefile)
      end
     
      def run
        while @reader.read do
          self.process_node()
        end
      end
     
      def process_node
        if @reader.name == 'Product' && reader.node_type == XML::Reader::TYPE_ELEMENT
          @file_handle.write(@reader.read_outer_xml)
          @reader.next
        end
      end
     
    end
     
    # Main
    XMLSplitProcessor.new(XML_FILE, "batch_%s.xml").run

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    septembre 2004
    Messages
    11 156
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : septembre 2004
    Messages : 11 156
    Points : 18 887
    Points
    18 887

    Par défaut

    Bien joué !

    J'ai pu constater ce matin qu'un programme Java à base de StAX ou de SAX en lecture/écriture bien écrit, faisait le job en une quinzaine de minutes.
    Mais, tu as trouvé avant que je ne fasse un rapport.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    novembre 2009
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : novembre 2009
    Messages : 176
    Points : 86
    Points
    86

    Par défaut

    Well done !

    Si tu as les même performances en Java, je suis preneur, ça m’éviterai de devoir installer ruby sur le serveur cible le moment venu

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/06/2009, 03h43
  2. XML/XSL et gestion des fichiers dans une application Web
    Par fatenatwork dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 01/02/2008, 14h09
  3. [PHP-JS] Ouverture d'un fichier selon une valeur d'une liste
    Par yacine mezzi dans le forum Syntaxe
    Réponses: 1
    Dernier message: 06/05/2007, 18h22
  4. Diviser un fichier selon une chaine de caractères
    Par navis84 dans le forum Fichiers
    Réponses: 4
    Dernier message: 19/06/2006, 11h51
  5. Boucle en Dos pour lister des fichiers selon une date
    Par Corben dans le forum Autres Logiciels
    Réponses: 1
    Dernier message: 17/12/2005, 12h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo