[gros volume inside] Enlever les balises xml et sauver en ascii

Enlever les balises xml et sauver en ascii [gros volume inside] - Shell/Batch - Programmation

Marsh Posté le 14-01-2004 à 17:56:58    

Bonjour,
J'ai une montagne de taf là et on viens de me filer un script à faire. Problême, j'ai que trés, mais alors trés peu de notion de bash.
A votre avis c'est simple à réaliser ? Il s'agit d'enlever toutes les balises d'un fichier xml et de l'enregistrer au format ascii. Je dois faire ça pour plus +de 25000 fichiers alors si quelqu'un à déja vu ça ça me sauverait un peu.
Merci d'avance :)

Reply

Marsh Posté le 14-01-2004 à 17:56:58   

Reply

Marsh Posté le 14-01-2004 à 18:10:01    

Tu installe un processeur XST (xalan par exemple), c'est exactement la transformation obtenue avec un fichier XSL sans traitement particulier.


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
Reply

Marsh Posté le 14-01-2004 à 18:15:26    

oui avec une pauvre regex :D

Reply

Marsh Posté le 20-01-2004 à 16:04:48    

Une solution avec sed, on supprime toutes les balises "<xxx>" (c'est assez bestial, mais cela suffit peut être) :
 

Code :
  1. sed -e 's/<[^<]*>//g' input_file

Reply

Marsh Posté le 20-01-2004 à 16:33:41    

C'est un peu moins simple: Faut supprimer les <xxx y="mmm"> les <xxx y="mmm"/> les </xxx>, les processing instructions, les commentaires
 
Il faut ensuite translater les entites caractere quand on le peut vers le caractere ascii (Isolatin1? Unicode?) correspondant.
 
A+,


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

Marsh Posté le 20-01-2004 à 18:54:44    

Bon, c'est pas du shell, mais si tu sais un peu coder le C:
- tu vas telecharger expat sur source forge (tu choisis le source unix ou pc selon tes besoins)
- tu lance l'auto configuration sous unix
- tu recompiles en faisant #undef sur les symboles XML_NS et XML_DTD (dans le fichier de config.h plateforme dependant, c'est lib/winconfig.h pour windows) ca fait un executable plus petit.
 
Si tout a ete ok jusque la (ca devrait), tu remplaces le fichier exemples/elements.c
Tu recompile l'executable correspondant, et tu obtient un exe qui fait ca et que tu peux adapter si besoin est (la je lui fait prendre un seul argument, le non du fichier a traiter, a toi de modifier ca selon ce qui t'arrange, et si la maniere dont les blancs sont geres ne te convient pas, tu peux modifier le code de characterData par exemple.
 

Code :
  1. /* This is simple demonstration of how to use expat. This program
  2.    reads an XML document from standard input and writes a line with
  3.    the name of each element to standard output indenting child
  4.    elements by one tab stop more than their parent element.
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "expat.h"
  9. static void XMLCALL
  10. characterData(void *userData, const char *s, int len)
  11. {
  12.   if (len)
  13.   {
  14.   char *buf = malloc(len+1);
  15.   strncpy(buf, s, len);
  16.   buf[len] = 0;
  17.   fputs(buf, stdout);
  18.   free(buf);
  19.   }
  20. }
  21. int
  22. main(int argc, char *argv[])
  23. {
  24.   char buf[BUFSIZ];
  25.   XML_Parser parser = XML_ParserCreate(NULL);
  26.   int done;
  27.   int depth = 0;
  28.   FILE *fin = fopen(argv[1], "r" );
  29.   if (!fin)
  30.   {
  31. fprintf(stderr, "cannot open file %s\n", argv[1]);
  32. return 1;
  33.   }
  34.   XML_SetUserData(parser, &depth);
  35.     XML_SetCharacterDataHandler(parser, characterData);
  36.   do {
  37.     size_t len = fread(buf, 1, sizeof(buf), fin);
  38.     done = len < sizeof(buf);
  39.     if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
  40.       fprintf(stderr,
  41.               "%s at line %d\n",
  42.               XML_ErrorString(XML_GetErrorCode(parser)),
  43.               XML_GetCurrentLineNumber(parser));
  44.       return 1;
  45.     }
  46.   } while (!done);
  47.   XML_ParserFree(parser);
  48.   fclose(fin);
  49.   return 0;
  50. }


 
Tu peux ensuite ajouter un handler pour les debuts et fins de tag, pour mieux controller quand tu veux des sauts de ligne...
Un exemple de modification ou je vire tous les blancs, tabs, saut de ligne... et envoie des sauts de ligne pour chaque tag fermant:
 

Code :
  1. /* This is simple demonstration of how to use expat. This program
  2.    reads an XML document from standard input and writes a line with
  3.    the name of each element to standard output indenting child
  4.    elements by one tab stop more than their parent element.
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "expat.h"
  9. static void XMLCALL
  10. characterData(void *userData, const char *s, int len)
  11. {
  12.   char *p, *q;
  13.   if (len)
  14.   {
  15.   char *buf = malloc(len+1);
  16.   strncpy(buf, s, len);
  17.   buf[len] = 0;
  18.   p = buf;
  19.   while (*p && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'))
  20.    p++;
  21.       q = buf + len;
  22.   while (q != p && (*q == ' ' || *q == '\t' || *q == '\n' || *q == '\r'))
  23.   {
  24.   *q = 0;
  25.    q--;
  26.   }
  27.   fputs(p, stdout);
  28.   free(buf);
  29.   }
  30. }
  31. static void XMLCALL
  32. startElement(void *data, const char *el, const char **attr)
  33. {
  34. }
  35. static void XMLCALL
  36. endElement(void *data, const char *el)
  37. {
  38. fprintf(stdout, "\n" );
  39. }
  40. int
  41. main(int argc, char *argv[])
  42. {
  43.   char buf[BUFSIZ];
  44.   XML_Parser parser = XML_ParserCreate(NULL);
  45.   int done;
  46.   int depth = 0;
  47.   FILE *fin = fopen(argv[1], "r" );
  48.   if (!fin)
  49.   {
  50. fprintf(stderr, "cannot open file %s\n", argv[1]);
  51. return 1;
  52.   }
  53.   XML_SetUserData(parser, &depth);
  54.   XML_SetCharacterDataHandler(parser, characterData);
  55.   XML_SetElementHandler(parser, startElement, endElement);
  56.   do {
  57.     size_t len = fread(buf, 1, sizeof(buf), fin);
  58.     done = len < sizeof(buf);
  59.     if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
  60.       fprintf(stderr,
  61.               "%s at line %d\n",
  62.               XML_ErrorString(XML_GetErrorCode(parser)),
  63.               XML_GetCurrentLineNumber(parser));
  64.       return 1;
  65.     }
  66.   } while (!done);
  67.   XML_ParserFree(parser);
  68.   fclose(fin);
  69.   return 0;
  70. }


 
A toi d'adapter selon tes besoins (decider d'envoyer ou pas un \n selon le nom du tag (pas pour des </b>, </i> par exemple) etc etc)
 
Tout ca devrait aussi pouvoir se coder assez facilement en perl, il y a un wrapper de expat en perl il me semble.
 
A+,


Message édité par gilou le 20-01-2004 à 19:03:21

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

Marsh Posté le 20-01-2004 à 19:19:16    

dit gilou vas faire un tour dans <ctype.h>
 
par contre pour ça
 
static void XMLCALL
  characterData(void *userData, const char *s, int len)
  {
      if (len)
      {
         char *buf = malloc(len+1);
         strncpy(buf, s, len);
         buf[len] = 0;
         fputs(buf, stdout);
         free(buf);
      }
  }  
 
 
ben faut pas voir peur ! un petit coup de fwrite peut faire du bon boulot (sauf emmerdemment sur système pourri)  
 
 
fprintf(stdout, "\n" );  -> fputs('\n', stdout);

Reply

Marsh Posté le 20-01-2004 à 22:38:55    

C'est quoi qui te defrise avec ces fputs?? une histoire de buffers flushés peut etre?
on va mettre fprintf(stdout, buf); a la place de fputs(buf, stdout); alors, et tout le monde sera content :D
 
Je vois pas l'interet de <ctype.h> ici, car je sais que les chaines retournées par expat sont en UTF-8 et donc pas dependant d'une locale ou un truc du meme tonneau. Bon d'accord on pourrait utiliser isspace, mais en l'occurence je suis pas certain que \f et \v doivent etre traites comme les autres.
 
Et puis je n'ai fait que donner qu'un exemple indicatif (d'ou mon emploi de fputs, le source original ayant puts, habituellement je reste fidele a fprintf :D)
A+,
 
 


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

Marsh Posté le 20-01-2004 à 22:53:44    

non y a rien : mais vous oubliez trop que printf est mal nommée c'est un affichage formaté, donc si tu n'a pas d'arguments à formater tu as quand même un surcout, même inutile. y a des fonctions pour autant s'en servir
 
pour ctype -> si

Reply

Sujets relatifs:

Leave a Replay

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