Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1646 connectés 

  FORUM HardWare.fr
  Programmation
  Shell/Batch

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

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

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

n°611805
kaiska
Posté le 14-01-2004 à 17:56:58  profilanswer
 

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 :)

mood
Publicité
Posté le 14-01-2004 à 17:56:58  profilanswer
 

n°611815
kadreg
profil: Utilisateur
Posté le 14-01-2004 à 18:10:01  profilanswer
 

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 !
n°611817
Taz
bisounours-codeur
Posté le 14-01-2004 à 18:15:26  profilanswer
 

oui avec une pauvre regex :D

n°616729
aigles
Posté le 20-01-2004 à 16:04:48  profilanswer
 

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

n°616740
gilou
Modérateur
Modzilla
Posté le 20-01-2004 à 16:33:41  profilanswer
 

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é!  --
n°616885
gilou
Modérateur
Modzilla
Posté le 20-01-2004 à 18:54:44  profilanswer
 

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é!  --
n°616905
Taz
bisounours-codeur
Posté le 20-01-2004 à 19:19:16  profilanswer
 

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);

n°617136
gilou
Modérateur
Modzilla
Posté le 20-01-2004 à 22:38:55  profilanswer
 

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é!  --
n°617152
Taz
bisounours-codeur
Posté le 20-01-2004 à 22:53:44  profilanswer
 

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


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Shell/Batch

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

 

Sujets relatifs
[PHP]Enlever popup ulimit ?Projet de gestion hasardeuse de frame (vrai défi inside)
conversion ascii[PHP] Récuperer un code HTML déjà généré ? (explication inside)
[ASM] Gros nb (oui c moi), j'ai pondu ce code plein d'érreurs...[Débutant inside] Choisir x et y en écrivant dans un Componant
[C++ 10 lignes inside] Probleme avec programme de cryptage XOR(newb' inside) cacher une div ?
[Latex] Vous utilisez quelle distro *TeX (pb de dvi inside)[Borland]Comment envoyer et récupérer une AnsiString (SendBuf inside)?
Plus de sujets relatifs à : [gros volume inside] Enlever les balises xml et sauver en ascii


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR