Created
January 3, 2018 18:34
-
-
Save zyzo/46f3187bd55b749ce5a51e607cafa92c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <float.h> | |
#include <math.h> | |
#include <string.h> | |
#include <stdbool.h> | |
#define length 1000 | |
#define file "xml.txt" | |
//Export | |
typedef struct xattribute_t xattribute_t; | |
typedef struct xelement_t xelement_t; | |
typedef union contenu contenu; | |
struct xattribute_t { | |
char *nom; | |
char *valeur; | |
xattribute_t *next; | |
}; | |
struct xelement_t { | |
char *nom ; | |
xattribute_t *liste; | |
xelement_t *pere; | |
xelement_t *frere; //next | |
union contenu { | |
char *raw ; | |
xelement_t *fils; | |
} *contenu; | |
}; | |
xelement_t *create_xelement (const char *name) { | |
xelement_t *a = (xelement_t*)malloc(sizeof(xelement_t)); | |
a->nom = malloc(sizeof(strlen(name)+1)); | |
strcpy (a->nom, name); | |
a->liste = NULL; | |
a->pere = NULL; | |
a->frere = NULL; | |
a->contenu = NULL; | |
return a; | |
} | |
xattribute_t *add_xattribute (xelement_t* e, const char *name, char *value) { | |
xattribute_t *n = (xattribute_t*)malloc(sizeof(xattribute_t)); | |
n->nom = malloc(sizeof(strlen(name)+1)); | |
n->valeur = malloc(sizeof(strlen(value)+1)); | |
strcpy (n->nom, name); | |
strcpy (n->valeur, value); | |
n->next = NULL; | |
//them vao duoi | |
xattribute_t *c = e->liste; | |
xattribute_t *p = NULL; | |
while (c != NULL) { | |
p = c; | |
c = c->next; | |
} | |
if (p != NULL) return p->next = n; | |
else return e->liste = n; | |
} | |
//them s vao nhanh con cua e | |
void add_sub_xelement (xelement_t *e, xelement_t *s) { | |
if (e->pere != NULL) return; | |
else { | |
e->contenu->fils = malloc(sizeof(xelement_t)); | |
e->contenu->fils->liste = malloc(sizeof(xattribute_t)); | |
e->contenu->fils->liste->nom = malloc(sizeof(strlen(s->liste->nom))+1); | |
e->contenu = malloc(sizeof(contenu)); | |
s->pere = e; | |
//them vao duoi | |
xelement_t *c = e->contenu->fils; | |
xelement_t *p = NULL; | |
while (c != NULL) { | |
p = c; | |
c = c->frere; | |
} | |
if (p != NULL) p->frere = s; | |
else e->contenu->fils = s; | |
// printf("%s\n",e->contenu->fils->liste->nom); | |
} | |
} | |
void add_raw (xelement_t *e, const char *r) { | |
e->contenu = (contenu*)malloc(sizeof(contenu)); | |
e->contenu->raw = malloc(sizeof(strlen(r)+1)); | |
strcpy (e->contenu->raw, r); | |
} | |
void delete_xelement(xelement_t *e) { | |
free (e); | |
free (e->pere); | |
free (e->frere); | |
free (e->contenu); | |
free (e->contenu->fils); | |
} | |
void save_xelement (FILE *fd, xelement_t *e) { | |
//ghi vao element | |
if (e == NULL) printf("Error\n"); | |
else { | |
e->contenu = (contenu*)malloc(sizeof(contenu)); | |
if (e->liste != NULL) { | |
fprintf (fd, "<%s ", e->nom); | |
xattribute_t *c = e->liste; | |
if (c-> next == NULL) fprintf(fd, "%s = \"%s\">",c->nom, c->valeur); | |
else { | |
while (c->next != NULL) { | |
fprintf(fd, "%s = %s /> ",c->next->nom, c->next->valeur); | |
c->next = c->next->next; | |
} | |
} | |
if (e->pere != NULL) save_xelement(fd, e->pere); | |
if (e->frere != NULL) save_xelement (fd, e->frere); | |
if(e->contenu->raw == NULL) return; | |
else fprintf(fd, " %s ",e->contenu->raw); | |
}else if (e->liste == NULL ) { | |
fprintf (fd, "<%s> ", e->nom); | |
if (e->pere != NULL) save_xelement(fd, e->pere); | |
if (e->frere != NULL) save_xelement (fd, e->frere); | |
if(e->contenu->raw == NULL) return; | |
else fprintf(fd, " %s ",e->contenu->raw); | |
fprintf (fd, "</%s> ", e->nom); | |
} | |
} | |
} | |
void save_xml (const char *fname, xelement_t *e) { | |
//mo file de viet | |
FILE *fi = NULL; | |
fi = fopen (fname,"w"); | |
if (fname == NULL) printf("\nError"); | |
else { | |
save_xelement (fi, e); | |
printf("\nsuccess\n"); | |
fclose (fi); | |
} | |
} | |
void print_xelement(xelement_t* e) { | |
save_xelement(stdout, e); | |
} | |
void test() { | |
xelement_t *b = create_xelement ("book"); | |
printf ("%s\t",b->nom); | |
add_xattribute(b,"id","102"); | |
printf ("%s = %s\t",b->liste->nom,b->liste->valeur); | |
add_xattribute(b,"ii","101"); | |
printf ("%s = %s\n",b->liste->next->nom,b->liste->next->valeur); | |
xelement_t *c = create_xelement ("titre"); | |
// add_sub_xelement (b,c); | |
printf ("%s\t",c->nom); | |
add_raw (c,"ten phim"); | |
printf ("%s\n",c->contenu->raw); | |
xelement_t *d = create_xelement ("book"); | |
// add_sub_xelement (c,d); | |
printf ("%s\t",d->nom); | |
add_xattribute(d,"id","102"); | |
printf ("%s = %s\t",d->liste->nom,d->liste->valeur); | |
} | |
//Import | |
char next_char (FILE *fd) { | |
if (fd == NULL) exit(1); | |
else { | |
char c = fgetc(fd); | |
fseek(fd, 0L, SEEK_SET); | |
do { | |
if (c == '\'') exit(1); | |
else if (c == '\n') exit(1); | |
else if (c == '\r') exit(1); | |
else if (c == '\t') exit(1); | |
else return c; break; | |
}while (c != EOF) ; | |
} | |
} | |
void check_next_char (FILE *fd, char c) { | |
if ( c != next_char(fd)) return; | |
} | |
bool is_next_char (FILE *fd, char c, bool cons) { | |
if (next_char(fd) == c) return true; | |
else cons = false; ungetc (next_char(fd), fd); return false; | |
} | |
//tra lai ten khi gao ki tu <>/= | |
char *next_word (FILE *fd) { | |
if (fd == NULL) exit(1); | |
else { | |
int n = 0; | |
int len = 0; | |
char s[len]; | |
char c; | |
c = fgetc(fd); | |
fseek(fd, 0L, SEEK_SET); | |
while (c != EOF) { | |
if (c == '<') {n++; s[len++] = c;} | |
else if (c == '>') {n++; s[len++] = c;} | |
else if (c == '/') {n++; s[len++] = c;} | |
else if (c == '=') {n++; s[len++] = c;} | |
else {s[len++] = c;} | |
if (n == 2) ungetc(c, fd); break; | |
} | |
s[len++] = '\0'; | |
char *p = s; | |
return p; | |
} | |
} | |
void check_next_word (FILE *fd, const char *w) { | |
int c = strcmp(next_word(fd),w); | |
if (c != 0) return; | |
} | |
//gao dau ngoac kep thu 2 thi ngung | |
char *next_string (FILE *fd) { | |
if (fd == NULL) exit(1); | |
else { | |
int n = 0; | |
int len = 0; | |
char s[len]; | |
char c; | |
c = fgetc(fd); | |
fseek(fd, 0L, SEEK_SET); | |
while (c != EOF) { | |
if (c == '\'') {n++; s[len++] = c;} | |
else {s[len++] = c;} | |
if (n == 3) break; | |
} | |
s[len++] = '\0'; | |
char *p = s; | |
return p; | |
} | |
} | |
//tra lai day ky tu den khi gap '<' (ko tinh vao day ky tu) lan 2 | |
char *next_raw (FILE *fd) { | |
if (fd == NULL) exit(1); | |
else { | |
int n = 0; | |
int len = 0; | |
char s[len]; | |
char c; | |
c = fgetc(fd); | |
fseek(fd, 0L, SEEK_SET); | |
while (c != EOF) { | |
if (c == '<') {n++; s[len++] = c;} | |
else {s[len++] = c;} | |
if (n == 2) break; | |
} | |
s[len++] = '\0'; | |
char *p = s; | |
return p; | |
} | |
} | |
xelement_t* load_xelement(FILE* fd, const char* end_tag); | |
void load_xelement_raw(FILE* fd, xelement_t* e) { | |
char* w = next_raw(fd); | |
check_next_char(fd, '<'); | |
check_next_char(fd, '/'); | |
check_next_word(fd, e->nom); | |
check_next_char(fd, '>'); | |
add_raw(e,w); | |
free(w); | |
} | |
void load_xelement_sub(FILE* fd, xelement_t* e) { | |
xelement_t* f = load_xelement(fd, e->nom); | |
if (f != NULL) { | |
add_sub_xelement(e,f); | |
load_xelement_sub(fd, e); | |
} | |
} | |
void load_xelement_content(FILE* fd, xelement_t* e) { | |
if (is_next_char(fd,'<',false)) | |
load_xelement_sub(fd, e); | |
else | |
load_xelement_raw(fd, e); | |
} | |
xelement_t* load_xelement(FILE* fd, const char* end_tag) { | |
xelement_t* e = NULL; | |
char c; | |
check_next_char(fd,'<'); | |
if ((end_tag) && (is_next_char(fd,'/',true))) { | |
check_next_word(fd,end_tag); | |
check_next_char(fd,'>'); | |
return NULL; | |
} | |
char* name = next_word(fd); | |
if (name == NULL) { | |
fprintf(stderr, "load_xelement: tag name expected\n"); | |
exit(EXIT_FAILURE); | |
} | |
e = create_xelement(name); | |
free(name); | |
while((name = next_word(fd)) != NULL) { | |
check_next_char(fd,'='); | |
char* value = next_string(fd); | |
add_xattribute(e,name,value); | |
} | |
c = next_char(fd); | |
if (c == '/') { | |
check_next_char(fd,'>'); | |
return e; | |
} | |
if (c == '>') { | |
load_xelement_content(fd, e); | |
return e; | |
} | |
fprintf(stderr, "load_xelement: end of markup expected ('>' or '/>'), but got %c\n", c); | |
exit(EXIT_FAILURE); | |
} | |
xelement_t* load_xml(const char* fname) { | |
FILE* fd = fopen(fname, "r"); | |
xelement_t* e = load_xelement(fd,NULL); | |
fclose(fd); | |
return e; | |
} | |
int main () { | |
test(); | |
FILE *fin ; | |
fin = fopen(file,"w"); | |
xelement_t *catalog = create_xelement ("catalog"); | |
xelement_t *book = create_xelement ("book"); | |
// add_sub_xelement (catalog,book); | |
add_xattribute (book,"id","bk101"); | |
xelement_t *author = create_xelement ("author"); | |
// add_sub_xelement (book,author); | |
add_xattribute (author,"lastname","Gambardella"); | |
add_xattribute (author,"firstname","Matthew"); | |
/* xelement_t *titre = create_xelement ("titre"); | |
add_sub_xelement (book,titre); | |
add_raw (titre,"XML Developer's Guide"); | |
xelement_t *genre = create_xelement ("genre"); | |
add_sub_xelement (book,genre); | |
add_raw (genre,"Computer"); | |
xelement_t *price = create_xelement ("price"); | |
add_sub_xelement (book,price); | |
add_raw (price,"44.95"); | |
xelement_t *publish_date = create_xelement ("publish_date"); | |
add_sub_xelement (book,publish_date); | |
add_raw (publish_date,"2000-10-01"); | |
xelement_t *description = create_xelement ("description"); | |
add_sub_xelement (book,description); | |
add_raw (description,"A former architect battles corporate zombies, an evil qorceress, and her own childhood to become queen of the world."); | |
*/ | |
print_xelement(catalog); | |
save_xml (file,catalog); | |
fclose (fin); | |
// load_xml (file); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment