transformer un fichier texte en XML

transformer un fichier texte en XML - Perl - Programmation

Marsh Posté le 16-01-2017 à 22:21:19    

Bonsoir à tous,
 
Je débute en perl et j'ai vraiment besoin de votre aide, en fait je dois développer un programme qui permet de transformer un fichier texte sous la forme suivante:  
 
(حاودته) الْحمى محاودة عاودته حينا بعد آخر وَيُقَال هُوَ يحاودنا بالزيارة يزورنا زيارات متقطعة وَفِي الْأَمر تأنى وَنظر فِيهِ مرّة بعد أُخْرَى
(حاذ)
عَلَيْهِ حوذا حَافظ وَالشَّيْء حاطه وَغلب عَلَيْهِ وَالدَّوَاب سَاقهَا سوقا عنيفا
(أحوذ) أسْرع وَيُقَال أحوذ السّير وَالدَّوَاب حاذها وَالشَّيْء جمعه وضمه وَالْقَصِيدَة أحكمها
(استحوذ) على الشَّيْء استولى وعَلى فلَان غَلبه وَيُقَال استحوذ عَلَيْهِ الشَّيْطَان وَفِي التَّنْزِيل الْعَزِيز {استحوذ عَلَيْهِم الشَّيْطَان فأنساهم ذكر الله}
(الأحوذي) المشمر فِي الْأُمُور القاهر لَهَا لَا يند عَلَيْهِ مِنْهَا شَيْء والسريع فِي كل مَا أَخذ فِيهِ والعالم بِالْأَمر
(الحاذ) الظّهْر وَيُقَال فلَان خَفِيف الحاذ قَلِيل المَال والعيال وَشَجر من الحمض يعظم منابته السهل والرمل وَهُوَ ناجع فِي الْإِبِل تخصب عَلَيْهِ رطبا ويابسا وَالْحَال (ج) أحواذ
(الحواذ) الْبعد
 
en un fichier xml comme suit:
 
<entry form="حاودته">
<defs>
<gloss>الْحمى محاودة عاودته حينا بعد آخر وَيُقَال هُوَ يحاودنا بالزيارة يزورنا زيارات متقطعة وَفِي الْأَمر تأنى وَنظر فِيهِ مرّة بعد أُخْرَى</gloss>
</defs>
</entry>
 
 
<entry form="حاذ">
<defs>
<gloss>عَلَيْهِ حوذا حَافظ وَالشَّيْء حاطه وَغلب عَلَيْهِ وَالدَّوَاب سَاقهَا سوقا عنيفا</gloss>
</defs>
</entry>
 
<entry form="أحوذ">
<defs>
<gloss>أسْرع وَيُقَال أحوذ السّير وَالدَّوَاب حاذها وَالشَّيْء جمعه وضمه وَالْقَصِيدَة أحكمها</gloss>
</defs>
</entry>
 
<entry form="استحوذ">
<defs>
<gloss>على الشَّيْء استولى وعَلى فلَان غَلبه وَيُقَال استحوذ عَلَيْهِ الشَّيْطَان وَفِي التَّنْزِيل الْعَزِيز</gloss>
<exemple>استحوذ عَلَيْهِم الشَّيْطَان فأنساهم ذكر الله</exemple> //la phrase entre {} présente exemple
</defs>
</entry>
 
<entry form="الأحوذي">
<defs>
<gloss>المشمر فِي الْأُمُور القاهر لَهَا لَا يند عَلَيْهِ مِنْهَا شَيْء والسريع فِي كل مَا أَخذ فِيهِ والعالم بِالْأَمر</gloss>
</defs>
</entry>
 
 
 
en attendant votre aide merci beaucoup d'avance.
 
 
 

Reply

Marsh Posté le 16-01-2017 à 22:21:19   

Reply

Marsh Posté le 17-01-2017 à 13:56:51    

SVP si personne peut me guider un peu..

Reply

Marsh Posté le 17-01-2017 à 23:27:26    

Code :
  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. open my $fh,  "<", "input.txt";
  7. open my $fh1, ">", "output.txt";
  8. while (<$fh> ) {
  9.    if (/\(([^)]*)\)(.*)/)  {
  10.     print $fh1 "<entry form=\"$1\">\n";
  11.     print $fh1 "\t<defs>\n";
  12.     print $fh1 "\t\t<gloss>$2</gloss>\n";
  13.     print $fh1 "\t</defs>\n";
  14.     print $fh1 "</entry>\n\n\n";
  15.    }
  16. }
  17. close $fh1;
  18. close $fh;


 
Chez moi ça marche.
Je vous laisse finir, j'ai pas traite le cas du tag exemple.
 
A+,


Message édité par gilou le 17-01-2017 à 23:30:24

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 17-01-2017 à 23:26:41    

Bonsoir à tous ,
 
c'est encore moi cherchant une solution ... j' ai essayé de développer un programme perl pour transformer un fichier texte en xml ,  
 

Code :
  1. #!/usr/lib/perl
  2. use strict;
  3. use warnings;
  4. use utf8;
  5. use XML::Writer;
  6. my $out;
  7. my $xml = XML::Writer->new(OUTPUT => \$out, DATA_MODE => 1, DATA_INDENT => '   ');
  8. $xml->xmlDecl();
  9. $xml->startTag('doc');
  10. open(my $fh, "<:utf8", '/home/lenovo/Bureau/txt_to_xml/input') or die "Failed to open file: $!\n";
  11. open my $fh1, ">:utf8", '/home/lenovo/Bureau/txt_to_xml/output.xml';
  12.  
  13. while (<$fh> ) {
  14.     chomp;
  15.      next if !length;
  16. my ($form, $gloss, $exple, $pluriel) = /
  17.  
  18.        \(([^\)]+)
  19.         \)(.*)
  20.         \(([^\)]+)
  21.         \%(.*)
  22.         /x;
  23.     $xml->startTag('entry', form => $form);
  24.     $xml->startTag('defs');
  25.     $xml->dataElement(gloss   => $gloss);
  26.     $xml->dataElement(exple => $exple);
  27.     $xml->dataElement(pluriel     => $pluriel);
  28.     $xml->endTag();
  29.     $xml->endTag();
  30. }
  31. $xml->endTag();
  32. $xml->end();
  33. print $fh1 $out;


 
par exemple pour le texte:  
(حاودته) الْحمى محاودة عاودته حينا بعد آخر وَيُقَال هُوَ يحاودنا بالزيارة يزورنا زيارات متقطعة وَفِي الْأَمر تأنى وَنظر فِيهِ مرّة بعد أُخْرَى
(حاذ)
عَلَيْهِ حوذا حَافظ وَالشَّيْء حاطه وَغلب عَلَيْهِ وَالدَّوَاب سَاقهَا سوقا عنيفا
(أحوذ) أسْرع وَيُقَال أحوذ السّير وَالدَّوَاب حاذها وَالشَّيْء جمعه وضمه وَالْقَصِيدَة أحكمها
(استحوذ) على الشَّيْء استولى وعَلى فلَان غَلبه وَيُقَال استحوذ عَلَيْهِ الشَّيْطَان وَفِي التَّنْزِيل الْعَزِيز {استحوذ عَلَيْهِم الشَّيْطَان فأنساهم ذكر الله}
(الأحوذي) المشمر فِي الْأُمُور القاهر لَهَا لَا يند عَلَيْهِ مِنْهَا شَيْء والسريع فِي كل مَا أَخذ فِيهِ والعالم بِالْأَمر
(الحاذ) الظّهْر وَيُقَال فلَان خَفِيف الحاذ قَلِيل المَال والعيال وَشَجر من الحمض يعظم منابته السهل والرمل وَهُوَ ناجع فِي الْإِبِل تخصب عَلَيْهِ رطبا ويابسا وَالْحَال (ج) أحواذ
(الحواذ) الْبعد  
 
je dois avoir le fichier xml suivant:  
<entry form="حاودته">
<defs>
<gloss>الْحمى محاودة عاودته حينا بعد آخر وَيُقَال هُوَ يحاودنا بالزيارة يزورنا زيارات متقطعة وَفِي الْأَمر تأنى وَنظر فِيهِ مرّة بعد أُخْرَى</gloss>
</defs>
</entry>
 
 
<entry form="حاذ">
<defs>
<gloss>عَلَيْهِ حوذا حَافظ وَالشَّيْء حاطه وَغلب عَلَيْهِ وَالدَّوَاب سَاقهَا سوقا عنيفا</gloss>
</defs>
</entry>
 
<entry form="أحوذ">
<defs>
<gloss>أسْرع وَيُقَال أحوذ السّير وَالدَّوَاب حاذها وَالشَّيْء جمعه وضمه وَالْقَصِيدَة أحكمها</gloss>
</defs>
</entry>
 
<entry form="استحوذ">
<defs>
<gloss>على الشَّيْء استولى وعَلى فلَان غَلبه وَيُقَال استحوذ عَلَيْهِ الشَّيْطَان وَفِي التَّنْزِيل الْعَزِيز</gloss>
<exemple>استحوذ عَلَيْهِم الشَّيْطَان فأنساهم ذكر الله</exemple> //la phrase entre {} présente exemple
</defs>
</entry>
 
<entry form="الأحوذي">
<defs>
<gloss>المشمر فِي الْأُمُور القاهر لَهَا لَا يند عَلَيْهِ مِنْهَا شَيْء والسريع فِي كل مَا أَخذ فِيهِ والعالم بِالْأَمر</gloss>
</defs>
</entry>  
 
en fait j'arrive pas à faire les expresions régulières permettant d'extraire les mots entre () , les phrases entre {} , etc  
en attendant votre aide merci d'avance
 
 
 
 
 
 
 
 
 

Reply

Marsh Posté le 17-01-2017 à 23:30:47    

Les sujets suivant ont été fusionnés à ce sujet par Gilou

  • regex perl


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 17-01-2017 à 23:38:57    

merci beaucoup gilou, est ce que vous pouvez m'expliquer un peu le code ?  
 
dans ce cas (il y a un retour à la ligne)  
(حاذ)
عَلَيْهِ حوذا حَافظ وَالشَّيْء حاطه وَغلب عَلَيْهِ وَالدَّوَاب سَاقهَا سوقا عنيفا
 
il affiche <gloss></gloss> au lieu <gloss>عَلَيْهِ حوذا حَافظ وَالشَّيْء حاطه وَغلب عَلَيْهِ وَالدَّوَاب سَاقهَا سوقا عنيفا</gloss> , comment peut on corriger ça ?
 
Merci encore une fois

Reply

Marsh Posté le 18-01-2017 à 01:46:26    

Si vous avez pas tout en une ligne, c'est un peu plus complexe, parce que au lieu de parser une ligne il faut considerer tous les types de ligne possible.
 

Code :
  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. open my $fh,  "<", "input.txt";
  7. open my $fh1, ">", "output.txt";
  8. my ($entry, $gloss, $exemple);
  9. while (<$fh> ) {
  10.    chop;
  11.    if (/^\(([^)]+)\)([^{]*)(\{(.*)\})?$/)  {
  12.     print_stuff($entry, $gloss, $exemple);
  13.     ($entry, $gloss, $exemple) = ($1, $2, $4);
  14.     next;
  15.    }
  16.    if (/^([^{]+)(\{(.*)\})?$/)  {
  17.     $gloss .= $1;
  18.     $exemple .= $3?$3:"";
  19.     next;
  20.    }
  21.    if (/^\{(.+)\}$/)  {
  22.     $exemple .= $1;
  23.     next;
  24.    }
  25. }
  26. print_stuff($entry, $gloss, $exemple);
  27. close $fh1;
  28. close $fh;
  29.  
  30. sub print_stuff {
  31.    my ($entry, $gloss, $exemple) = (shift, shift, shift);
  32.    return unless($entry);
  33.    print $fh1 "<entry form=\"$entry\">\n";
  34.    print $fh1 "\t<defs>\n";
  35.    print $fh1 "\t\t<gloss>$gloss</gloss>\n";
  36.    print $fh1 "\t\t<exemple>$exemple</exemple>\n" if ($exemple);
  37.    print $fh1 "\t</defs>\n";
  38.    print $fh1 "</entry>\n\n\n";
  39. }


 
A vous d’améliorer (ajouter un blanc entre deux chaines concaténées si nécessaire, etc)
 
A+,


Message édité par gilou le 18-01-2017 à 02:00:56

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-01-2017 à 13:49:31    

c'est un peu tard, mais vraiment c'est comme de la magie Bravo gilou et merci beaucoup

Reply

Marsh Posté le 18-01-2017 à 14:12:37    

est ce que vous pouvez m'expliquer un peu ce ces lignes de code ?  
 

Code :
  1. if (/^\(([^)]+)\)([^{]*)(\{(.*)\})?$/)  {
  2.     
  3.    }
  4.    if (/^([^{]+)(\{(.*)\})?$/)  {
  5.     $gloss .= $1;
  6.     $exemple .= $3?$3:"";
  7.     next;
  8.    }
  9.    if (/^\{(.+)\}$/)  {
  10.     $exemple .= $1;
  11.     next;
  12.    }
  13. }


 
A vous d’améliorer (ajouter un blanc entre deux chaines concaténées si nécessaire, etc)
 
A+,[/quotemsg]

Reply

Marsh Posté le 18-01-2017 à 21:56:19    

if (/^\(([^)]+)\)([^{]*)(\{(.*)\})?$/)
Si la ligne complète ^...$ peut se décomposer en  
\(([^)]+)\) : une expression parenthésée \(...\) contenant un groupe (...) contenant des + caractères différents de ): [^)]
([^{]*) : un second groupe contenant 0 ou des * caractères différents de {: [^{]
(\{(.*)\})? : un groupe optionnel (...)? contenant  
                  \{(.*)\} : une expression accoladée \{...\}  contenant un groupe (...) contenant 0 ou des * caractères .
Bref la première expression c'est pour capturer une expression entre parenthèse et s’arrêter a la première parenthèse fermante car par défaut sur (xxx)yyy(zzz) perl capturerait tout si on cherchait avec \((.*)\)  
La seconde pour capturer ce qui suit en s’arrêtant au premier {
El la dernière c'est pour capturer une expression entre accolades et s’arrêter a la première accolade fermante
 
Des expressions régulières plus réalistes tenant compte de possible blancs entre les champs, etc, auraient plutôt cet aspect:

Code :
  1. while (<$fh> ) {
  2.    chop;
  3.    if (/^\s*\((.*?)\)\s*(.*?)\s*(?:\{(.*?)\})?\s*$/) {
  4.     print_stuff($entry, $gloss, $exemple);
  5.     ($entry, $gloss, $exemple) = ($1, $2, $3);
  6.     next;
  7.    }
  8.    if (/^\s*(.*?)\s*(?:\{(.*?)\})?\s*$/) {
  9.     $gloss .= $1;
  10.     $exemple .= $2?$2:"";
  11.     next;
  12.    }
  13.    if (/^\s*\{(.*?)\}\s*$/) {
  14.     $exemple .= $1?$1:"";
  15.     next;
  16.    }
  17. }


 
A+,


Message édité par gilou le 18-01-2017 à 22:21:41

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-01-2017 à 21:56:19   

Reply

Marsh Posté le 18-01-2017 à 22:09:40    

comment je peux modifier le code pour avoir  
<entry form="الْبَين">
<defs>
<gloss> الْوَاضِح والطلق اللِّسَان الفصيح </gloss>
</defs>
</entry>
 
au lieu de  
 
<entry form="الْبَين">
<defs>
<gloss> الْوَاضِح والطلق اللِّسَان الفصيح (ج) أبيناء وبيناء وأبيان  </gloss>
</defs>
</entry>
 
c'est à dire je m'arrete toujours au premier parenthèse rencontré

Reply

Marsh Posté le 18-01-2017 à 22:36:19    

Remplacer  
if (/^\s*\((.*?)\)\s*(.*?)\s*(?:\{(.*?)\})?\s*$/) {
par
if (/^\s*\((.*?)\)\s*(.*?)\s*(?:\(.*)?(?:\{(.*?)\})?\s*$/) {
et
if (/^\s*(.*?)\s*(?:\{(.*?)\})?\s*$/) {
par
if (/^\s*(.*?)\s*(?:\(.*)?(?:\{(.*?)\})?\s*$/) {
 
Bref rajouter un (?:\(.*)? qui va passer a la trappe un caractère ( et tous les caractères qui suivent, tant qu'un caractère { ou une fin de ligne n'est pas rencontrée (voir le (?:\{(.*?)\})?\s* qui suit)
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 18-01-2017 à 22:43:53    

ça marche à merveille, merciii infiniment :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed