IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Modules Perl Discussion :

Fusion de fichiers XML - utilisation des handlers (XML::Twig) ?


Sujet :

Modules Perl

  1. #21
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 25
    Par défaut
    Bon j'ai regardé, c'est nickel Philou merci pour les mise à jour que t'as faites. C'est beaucoup plus clair comme ça.

    Par contre j'ai beau changer 'findnodes' en 'children', ou alors utiliser 'field', ou même d'autres solutions.... rien ne solutionne mon problème avec Twig.

    Je pense que c'est mon parsing qui est mauvais, donc il ne peut pas reprendre le texte sous 'headword'. J'vais revoir ça.

    Sinon philou, tu penses que passer par les Regexp. c'est possible pour la fusion ?

  2. #22
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Je pense, en fait, qu'il faut conserver l'usage d'un parser, et qu'il ne devrait pas être nécessaire de découper le fichier d'entrée pour le fournir au parser, car c'est justement son boulot de séparer les éléments sémantique du fichier XML.
    Je devrais avoir un peu plus de temps aujourd'hui pour me pencher sur le module XML::TWIG

  3. #23
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Je n'ai vraiment pas eu le temps de me pencher sur ton souci, mais je fais confiance à philou (à qui je recommande de découvrir ce module qui est très performant).

  4. #24
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 25
    Par défaut
    Malheureusement, je n'utilise Twig que depuis peu, et j'ai un peu de mal avec les explications en anglais. Je fais donc beaucoup de choses selon les exemples que je trouve (ou selon les articles de Developpez.com). Et je n'ai pas trouvé d'exemples de fusion en utilisant non pas un système DOM mais un système SAX (pour les gros fichiers).

    Twig est décrit comme pouvant fusionner (merging) les fichiers Xml, sans restriction. Je suppose dans ce cas que les handlers fonctionnent.

    J'avais essayé au début sans passé par un pré-découpage. On pointe sur 'entry' le twig-handler (ça tu l'as dans mon code si tu veux philou). Quand on parse les fichiers, on entre dans la subroutine qui doit effectuer un traitement particulier, puis retourner l'entrée.

    Ceci marche sans aucun problème avec un seul fichier, mais gérer deux fichiers en même temps... c'est ça le problème. Comment parser simultanément deux fichiers, en sachant que l'avancement du parsing dépend de la comparaison entre les deux ?

    N'avoir qu'une entrée pour le parsing permet d'avancer entrée par entrée, c'est un peu le mode "rustine" d'une utilisation réelle des handlers.

    Ce qu'il faudrait :
    1) je ne parse que la première entrée des deux fichiers, je renvoie les valeurs.
    2) je compare
    3) selon la comparaison, j'avance ou pas dans les fichiers vers l'entrée suivante.

    Ce principe, en DOM, aucun problème. En SAX, je n'arrive pas à le concevoir. ça voudrait dire que le parsing est partiel et en attente d'un nouveau lancement..... Il faudrait indicer le handler en fait, par exemple un $i qui prend 0 au départ, puis pour avancer on l'incrémente. Si on avance pas on sera toujours à 0. Mais je ne sais même pas si on peut faire ça, une sorte de :
    Twig_handlers => 'entry'[$i] => \&twig_entry

    J'ai jamais vu un tel exemple. Et je ne sais même pas si ça pourrait marcher. Peut être que ça t'aidera.

  5. #25
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    J'ai compris le problème en testant et lisant la doc. Une fois l'un des parser appelé, il parcours le contenu de la chaine fournie en entrée à la recherche d'un document XML valide. Il ne retourne alors une erreur si la chaine fournie est incomplète, et un arbre s'il est complet.
    Ainsi, en fournissant un fichier en entrée, il va le parcourir en totalité sans rendre la main à l'algorithme de fusion pour lire et comparer avec l'autre parser (hormis que lors de l'appel au handler).

    Je comprends donc aussi le besoin que tu avais de fournir des fragments XML valides au parser pour qu'il retourne un arbre contenant un entry valide.

    J'ai donc modifié et corrigés quelques bugs de la dernière version, et j'obtiens quelque chose qui me semble fonctionner.
    Attention, j'ai modifié les tests de comparaison de ton script initial pour réduire le nombre de branches en utilisant un opérateur de comparaison qui intègre à la fois le fait qu'un entry soit trouvé, et l'ordre lexical des headword. Mais tu pourras revenir à ta version initiale sans problème.
    Parmi les bugs corrigés :
    - le chemin xpath pour accéder à headword depuis root est //headword
    - le retour de findnodes est un tableau dont il faut prendre le premier élément pour obtenir le texte du headword
    - le copy -> paste dans fusion ne fonctionne pas car la méthode copy ne détache pas l'élément de son arbre initial. Or, pour utiliser paste, il faut que l'élément ne soit pas attaché à un arbre. Il faut donc utiliser cut et paste (voir doc XML::Twig::Elt).

    Le script:
    Code : 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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    #!/usr/bin/perl
     
    # =======================================================================================================================================
    ###--- METADIRECTIVES ---###
     
    use strict;
    use warnings;
    use utf8;
    use IO::File; 
    use Getopt::Long; # pour gérer les arguments.
     
    use XML::Twig; # (non inclus dans le core de Perl), pour le parsing de la source.
    use XML::Writer; # (non inclus dans le core de Perl), pour le fichier de sortie.
     
     
    # =======================================================================================================================================
    ###--- PROLOGUE ---###
     
    my $ref_root = 'volume'; # la racine (par exemple : <volume> ou <dictionary>).
    my $ref_entry = 'entry'; # l'élément dans la source qui correspond avec <m:entry> dans MAM.
    my $ref_headword = 'headword';
    my $ref_sense = 'sense'; # idem pour l'élément <sense> dans MAM.
     
    # ------------------------------------------------------------------------
    ##-- Gestion des options --##
     
    my ($date, $FichierOne, $FichierTwo, $FichierResultat, $erreur, $encoding) = ();
    my ($verbeux, $help, $pretty_print, $langue) = ();
    GetOptions( 
      'date|time|t=s'        	    => \$date, # flag de type -date ou --date, ou -time ou --time, ou -t ou --t (=s : string)
      'source|base|in|one|from|i=s' => \$FichierOne, 
      'add|and|two|j=s'        		=> \$FichierTwo,
      'sortie|out|to|o=s'           => \$FichierResultat, 
      'erreur|error|e=s'     	  	=> \$erreur, 
      'encodage|encoding|enc|f=s' 	=> \$encoding, 
      'help|h'                	  	=> \$help, 
      'verbeux|v'             	  	=> \$verbeux, 
      'print|pretty|p=s'       	  	=> \$pretty_print, 
      'langue|lang|l=s'				=> \$langue,
      );
     
    if (!( defined $date ))
    	{
    	$date = localtime;
    	};
    if (!( defined $FichierOne ))
    	{
    	&help ; # si le fichier source n'est pas spécifié, affichage de l'aide.
    	};
    if (!( defined $FichierTwo ))
    	{
    	&help ; # si le fichier source n'est pas spécifié, affichage de l'aide.
    	};
    if (!( defined $FichierResultat ))
    	{
    	$FichierResultat = "toto.xml" ;
    	};
    if (!( defined $erreur ))
    	{
    	$erreur = "|ERROR| : problem opening file :";
    	};
    if (!( defined $encoding ))
    	{
    	$encoding = "UTF-8"; 
    	};
    if (!( defined $pretty_print ))
    	{
    	$pretty_print = "none"; 
    	};
    if (!( defined $langue ))
    	{
    	$langue = "XX"; 
    	};
    if ( defined $help )
    	{
    	&help;
    	};
     
    # ------------------------------------------------------------------------
    # Autres variables :
     
    my $count_one = 0;
    my $count_two = 0;
     
    # ------------------------------------------------------------------------
    # Input/ Output
     
    open (FILEONE, "<:encoding($encoding)", $FichierOne) or die ("$erreur $!\n");
    open (FILETWO, "<:encoding($encoding)", $FichierTwo) or die ("$erreur $!\n");
     
    # ------------------------------------------------------------------------
     
    if ( defined $verbeux )
    	{
    	&info('a'); 
    	};
    # message dans le STDERR (voir subroutine 'info') indiquant le démarrage du programme.
     
    # ------------------------------------------------------------------------
    ##-- Début de l'écriture --##
     
    my $output = new IO::File(">$FichierResultat");
    my $writer = new XML::Writer(
      OUTPUT      => $output,
      DATA_INDENT => 3,         # indentation, 3 espaces
      DATA_MODE   => 1,         # changement ligne.
      ENCODING    => $encoding,
    );
    $writer->xmlDecl($encoding);
     
    $writer->startTag
    	(
      "m:volume",
      'name'              => "NAME",
      'source-language'   => $langue,
      'creation-date'     => $date,
    	);
     
    # =======================================================================================================================================
    ###--- PREPARATION ---###
     
    my ($twig_one, $twig_two);
    my ($entry_one, $entry_two);
    $twig_one = XML::Twig->new
      (
       output_encoding => $encoding, # on reste en utf8
       pretty_print    => $pretty_print, # par défaut le style est 'none'
       twig_roots      => {'entry' => 1}, 
       Twig_handlers   => {'entry' => \&entry_one},
      );
     
    sub entry_one {
      $entry_one = $_[1];
      return 1;
    }
     
    # ------------------------------------------------------------------------
    $twig_two = XML::Twig->new
      (
       output_encoding => $encoding, 
       pretty_print    => $pretty_print,
       twig_roots      => {'entry' => 1},
       Twig_handlers   => {'entry' => \&entry_two},
      );
     
    sub entry_two{
      $entry_two = $_[1];
      return 1;
    }
     
    # ------------------------------------------------------------------------
     
    if ( defined $verbeux )
    	{
    	&info('b'); 
    	};
     
    # ------------------------------------------------------------------------
     
    $entry_one = next_entry($twig_one, *FILEONE, \$entry_one); # obtenir la première entrée de la source 1.
    $entry_two = next_entry($twig_two, *FILETWO, \$entry_two); # obtenir la première entrée de la source 2.
     
    # ------------------------------------------------------------------------
     
    if ( defined $verbeux )
    	{
    	&info('c'); 
    	};
     
    # =======================================================================================================================================
    ###--- ALGORITHME DE LA FUSION ---###
     
    # Après avoir récupéré la ou les entrées (sub next_entry), on les compare.
    # On écrit dans le fichier de sortie selon la comparaison.
    my ($headword_one, $headword_two);
    # Le traitement continuera tant qu'il y a des entrées dans l'une ou l'autre source.
    while ($entry_one || $entry_two)
      {
        if ( defined $verbeux )	{print (STDERR "In progress\n");};
     
        $headword_one = $entry_one ? [$entry_one->findnodes ("//headword")]->[0]->text : undef;
        $headword_two = $entry_two ? [$entry_two->findnodes ("//headword")]->[0]->text : undef;
        if ( defined $verbeux && $headword_one )	{print (STDERR "$FichierOne : entrée [$headword_one]\n");};
        if ( defined $verbeux && $headword_two )	{print (STDERR "$FichierTwo : entrée [$headword_two]\n");};
     
        # On compare la présence des headword, et s'ils sont présents tous les deux,
        # on compare les deux headword 'lexicographiquement'
        my $compare = (defined $headword_two) - (defined $headword_one) || $headword_one cmp $headword_two;
     
        # 1) si l'entrée 1 est inférieure à l'entrée 2 (ou s'il n'y a plus d'entrée 2):
        # On écrit l'entrée 1 dans le fichier de sortie.
        # On avance d'une entrée dans le fichier 1
        if ($compare < 0) {
          $entry_one->print($output, "indented");
          # pour avoir l'entrée suivante dans le fichier 1.
          $entry_one = next_entry($twig_one, *FILEONE, \$entry_one);
        }
        # 2) si l'entrée 1 est supérieure à l'entrée 2 (ou s'il n'y a plus d'entrée 1):
        # On écrit l'entrée 2 dans le fichier de sortie.
        # On avance d'une entrée dans le fichier 2.
        elsif ($compare > 0) {
          $entry_two->print($output, "indented");
          # pour avoir l'entrée suivante dans le fichier 2.
          $entry_two = next_entry($twig_two, *FILETWO, \$entry_two);
        }
        # 3) le dernier cas : entrée 1 = entrée 2 :
        # On ajoute les éléments de entrée 2 dans entrée 1, qu'on écrit dans le fichier de sortie.
        # On avance d'une entrée dans le fichier 1 et dans le fichier 2.
        else
          {
            fusion ($entry_one, $entry_two);
            $entry_one->print($output, "indented");
            $entry_one = next_entry($twig_one, *FILEONE, \$entry_one);
            $entry_two = next_entry($twig_two, *FILETWO, \$entry_two);
          }
      }
     
    # ------------------------------------------------------------------------
    # Fin de l'écriture :
     
    $writer->endTag("m:volume");
    $output->close();
     
    # ------------------------------------------------------------------------
     
    if ( defined $verbeux )
      {
        &info('d');
      };
     
    # =======================================================================================================================================
    ###--- SUBROUTINES ---###
    sub next_entry {
      my ($twig, $file, $entry) = @_;
     
      $$entry = undef;
      $/ = "</entry>";
      while (!$$entry && !eof $file) {
        my $xml = <$file>;
        $twig->safe_parse($xml);
      }
      $twig->purge;
     
      return $$entry;
    }
     
    # ------------------------------------------------------------------------
     
    sub fusion
    {
    my $entry_one = shift @_;
    my $entry_two = shift @_;
     
    foreach my $sense_two ($entry_two->findnodes('sense'))
      {
        $sense_two->cut;
        my $last_elt = $entry_one->last_child('sense');
        $last_elt = $entry_one->last_child('head') if !defined $last_elt;
     
        $sense_two->paste('after' => $last_elt);
      }
    return ($entry_one);
    }
     
    # ------------------------------------------------------------------------
     
    sub info
    {
    my $info = shift @_;
    if ($info =~ 'a')
    	{
    	print (STDERR "================================================================================\n");
    	print (STDERR "\t~~~~ $0 : START ~~~~\n");
    	print (STDERR "================================================================================\n");
    	}
    elsif ($info=~ 'b')
    	{
    	print (STDERR "================================================================================\n");
    	print (STDERR "en-tete du fichier de sortie effective\n");
    	print (STDERR "--------------------------------------------------------------------------------\n");
    	}
    elsif ($info=~ 'c')
    	{
    	print (STDERR "================================================================================\n");
    	print (STDERR "lancement du processus de fusion\n");
    	print (STDERR "--------------------------------------------------------------------------------\n");
    	}
    elsif ($info =~ 'd')
    	{
    	print (STDERR "~~~~ $0 : END ~~~~\n");
    	print (STDERR "================================================================================\n");
    	my $time = times ;
    	my $FichierLog = 'LOG.txt';
    	open(my $FiLo, ">>:encoding($encoding)", $FichierLog) or die ("$erreur $!\n");
    	print {$FiLo}
    	"==================================================\n",
    	"RAPPORT : ~~~~ $0 ~~~~\n",
    	"--------------------------------------------------\n",
    	"Fichier source : $FichierOne\n",
    	"--------------------------------------------------\n",
    	"Fichier final : $FichierResultat\n",
    	"--------------------------------------------------\n",
    	"Date du traitement : ", $date, "\n",
    	"--------------------------------------------------\n",
    	"Lapsed time : ", $time, " s\n",
    	"==================================================\n";
    	}
    }
     
     
    sub help 
    {
    print (STDERR "================================================================================\n");  
    print (STDERR "HELP\n");
    print (STDERR "================================================================================\n");
    print (STDERR "usage : $0 -i <sourcefile.xml> -o <outfile.xml>\n\n") ;
    print (STDERR "options : -h affichage de l'aide\n") ;
    print (STDERR "          -e le message d'erreur (ouverture de fichiers)\n") ;
    print (STDERR "          -f le format d'encodage\n");
    print (STDERR "          -v mode verbeux (STDERR et LOG)\n");
    print (STDERR "          -t pour la gestion de la date (initialement : localtime)\n");
    print (STDERR "================================================================================\n");
    }
     
     
    # =======================================================================================================================================
    1 ;

  6. #26
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 822
    Par défaut
    Alors sympa ce module ?

  7. #27
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Disons... pour la problématique de japanatome, il est clair que l'usage d'un parser XML par handler pose des problèmes.
    Concernant l'usage de XML::Twig en lui-même, je sais pas trop, mais si je suis amené à parser du XML, je commencerai par utiliser ce module

  8. #28
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 25
    Par défaut
    Hé bé .... J'suis ému...



    Merci Philou pour le temps que tu as passé et les explications. Non seulement tu me proposes un code qui marche, mais en plus tu me dis pourquoi il marchait pas.

    Je vais regarder ça. En tout cas je peux déjà faire deux conclusions :

    1) Tous les chemins mènent à Perl (interprétation de "There is more than one way to do it"), mais certains chemins ne sont pas évidents du tout, la preuve par les handlers et ma problématique.
    Jusqu'à ce matin je basculais entre un fonctionnement en Regex avec mon fameux while <IN>, et le parseur. De ce mélange de deux méthodes il fallait choisir. Philou m'a bien aidé pour ce choix .

    2) Il va vraiment falloir que je bosse mon anglais .... Parce que mine de rien, la doc' sur CPAN et sur le site de l'auteur de Twig est quand même bien développé (c'est d'ailleurs pour ça que j'ai choisi Twig).

    Bon je vérifie tout ça, et je met [résolu] après.

    Une dernière question, à Djibril et à Philou, mais peut être un peu trop personnel : Vous "faites" du Perl depuis longtemps ? Parce que la différence de comportement entre vous deux et moi (qui ai commencé il y a 3 mois) est flagrante.

  9. #29
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    La solution proposée ne me satisfait guère, car elle n'est pas transposable à d'autres problématiques de merge de fichier XML (à cause de la nécessité de fragmenter le fichier XML pour le parser fragment par fragment).
    Je reste donc sur ma faim. Il me semble qu'il faudrait soit :
    - trouver le parser vraiment adapté (qui accepte d'emblée des fragments de fichier XML)
    - adapter le parser actuel pour qu'il accepte ce type de fragment

    J'ai commencé perl avec la version 5.05, vers 1998, après avoir usé awk. Je l'ai intensivement utilisé professionnellement pendant 3 ans, de 2005 à 2008, et maintenant, surtout pour le plaisir.

  10. #30
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 25
    Par défaut
    ça marche nickel ! Sur mes gros fichiers, je met moins de 10 minutes, ce qui est très bien !

    Pour ton idée de généraliser, c'est peut-être possible en remplaçant le handler 'entry' par $tag, qui peut être utilisé après pour $/ :

    $/ = "</$tag>";

    Ensuite dans le while, on peut remplacer "//headword" par un $comp pour l'élément à comparer.

    Et dans la sub fusion, 'sense' devient $merging_elt (l'élément à fusionner) et 'head' $merging_place (le lieu de la fusion si $merging_elt n'apparaît pas là ou aura lieu a fusion).

    En faisant juste ça, on s'en sort bien non ?


    [EDIT : ça ne répond pas à ta question, désolé pour avoir répondu à côté ]


    Pour ma part, je n'essaierai pas d'aller plus loin, puisque j'ai une version qui marche. Sauf si tu veux continuer, dans ce cas je peux essayer d'apporter mon aid.... mon soutien psychologique

  11. #31
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Citation Envoyé par japanatome Voir le message
    ça marche nickel ! Sur mes gros fichiers, je met moins de 10 minutes, ce qui est très bien !

    Pour ton idée de généraliser, c'est peut-être possible en remplaçant le handler 'entry' par $tag, qui peut être utilisé après pour $/ :

    $/ = "</$tag>";
    Oui, tant que l'on n'a qu'un seul type de tag à récupérer...
    Et cela ne règle nullement le problème de la présence de multiples tags différents dans le fichier source, même si l'on ne souhaite en traiter qu'un seul type.
    Bref, cela reste une solution spécifique.

    [EDIT : ça ne répond pas à ta question, désolé pour avoir répondu à côté ]
    Tu es concentré sur ton problème, c'est donc normal.
    Pour ma part, je n'essaierai pas d'aller plus loin, puisque j'ai une version qui marche. Sauf si tu veux continuer, dans ce cas je peux essayer d'apporter mon aid.... mon soutien psychologique
    Question subsidiaire : les deux fichiers XML à merger sont-ils géant, ou seulement l'un des deux ?

  12. #32
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 25
    Par défaut
    Les deux le sont. En fait, j'en ai plus que deux, mais en moyenne ils font 50 mo. Soit ils ont beaucoup d'entrées (jusqu'à 100 000), soit ils ont beaucoup d'informations (mais dépassent les 20 000 entrées quand même).
    Sinon j'aurai fait un parsing complet sur le petit, et un handler sur le plus gros
    Je suis en train d'apporter des améliorations (sur la subroutine fusion, pour fusionner un peu plus).
    Et je viens de me rendre compte d'un point très important :
    'cmp' (ou autre fonction de comparaison sur les chaînes), utilise l'ordre ASCII ! Et moi je travaille avec des sources Unicode et ASCII, et donc l'ordre change.... Va falloir trier tout ça !

    Sinon même en enchaînant les fusions, ça marche nickel, et la moyenne reste sur 10 minutes environ (pour obtenir un fichier entre 80 et 100mo au final).

  13. #33
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Je suis sur une piste qui utilise les thread et des pipes.

  14. #34
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 25
    Par défaut
    Si jamais tu trouves quelque chose, tu auras au moins une personne dans ton fan club

    la continuité de cette problématique m'intéresse toujours !

  15. #35
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Je bloque : j'arrive à créer correctement des pipes et des threads, mais il semblerait que XML:arser::Expat n'accepte pas un file handle issu d'un pipe comme entrée à parser, car je n'arrive pas à l'alimenter comme je le souhaite.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Utiliser des données XML avec Excel ?
    Par sky1989 dans le forum Excel
    Réponses: 3
    Dernier message: 29/03/2012, 22h48
  2. doc XML utiliser des conditions
    Par clouddd dans le forum C#
    Réponses: 5
    Dernier message: 07/06/2011, 15h00
  3. Réponses: 1
    Dernier message: 29/04/2009, 11h43
  4. [xslt][xpath]Utilisation des attributs XML
    Par Little_flower dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 15/05/2007, 13h42
  5. Réponses: 1
    Dernier message: 01/07/2006, 12h18

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