source: gaycko/trunk/src/dom/dom.c @ 4740

Last change on this file since 4740 was 4740, checked in by Jean-Yves Lamoureux, 10 years ago
  • Use GNU_SOURCE to ensure availability of strdup&co
  • Fix signedness warnings
File size: 3.6 KB
Line 
1#include <config.h>
2#include <stdio.h>
3#include <string.h>
4#include "dom.h"
5#include "helpers/str.h"
6
7gDOM *gaycko_convert_dom(htmlDocPtr doc) {
8
9        gDOM *dom = malloc(sizeof(gDOM));
10        dom->root = NULL; 
11        htmlNodePtr root = xmlDocGetRootElement(doc);
12        gElement **r = NULL;
13        gElement *ret = NULL;
14
15        if(root != NULL)
16        {
17                ret = explore(r, root, 0, NULL);
18        }
19
20        dom->root = ret;
21        pretty_print(ret);
22
23        return dom;
24}
25
26
27gElement *add_element(htmlNodePtr node) {
28
29        gElement *e;
30        e = malloc(sizeof(gElement));
31        e->children_count  = 0;
32        e->children        = NULL;
33        e->attribute_count = 0;
34        e->attributes      = NULL;
35
36        if(!node->name) {
37                e->name = strdup("UNKNOW");
38                e->type = ELEM_UNKNOW;
39                return e;       
40        }
41       
42        e->name = (char*)strdup((const char*)node->name);
43        if(!strncmp(e->name, "html", 4)) {
44                e->type = ELEM_HTML;
45        }else if(!strncmp(e->name, "head", 4)) {
46                e->type = ELEM_HEAD;
47        }else if(!strncmp(e->name, "title", 5)) {
48                e->type = ELEM_TITLE;
49        }else if(!strncmp(e->name, "meta", 4)) {
50                e->type = ELEM_META;
51        }else if(!strncmp(e->name, "body", 4)) {
52                e->type = ELEM_BODY;
53        }else if(!strncmp(e->name, "h1", 2)) {
54                e->type = ELEM_H1;
55        }else if(!strncmp(e->name, "br", 2) || !strncmp(e->name, "br ", 3)) {
56                e->type = ELEM_BR;
57        }else if(!strncmp(e->name, "p", 1)) {
58                e->type = ELEM_P;
59        }else if(!strncmp(e->name, "img", 3)) {
60                e->type = ELEM_IMG;
61        }else if(!strncmp(e->name, "table", 3)) {
62                e->type = ELEM_TABLE;
63        }else if(!strncmp(e->name, "tr", 3)) {
64                e->type = ELEM_TR;
65        }else if(!strncmp(e->name, "td", 3)) {
66                e->type = ELEM_TD;
67        }else if(!strncmp(e->name, "text", 4)) {
68                e->type = ELEM_TEXT;
69                e->text = (char*)strdup((const char*)xmlNodeGetContent(node));
70                strip_eol(e->text);
71                strip_spaces(e->text);
72        }else {
73                e->type = ELEM_UNKNOW;
74                printf("Unknow tag '%s'\n", e->name);   
75        }
76
77        if(node->properties) {
78                for(xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
79                        e->attributes = realloc(e->attributes, sizeof(gAttribute));
80                        e->attributes[e->attribute_count].name = strdup((const char*)attr->name);
81                        e->attributes[e->attribute_count].value = strdup((char*)attr->children->content);
82            e->attribute_count++;
83                }
84        }
85
86        return e;
87}
88
89
90gElement* explore(gElement **elem, htmlNodePtr element, unsigned int level, gElement *parent)
91{
92        unsigned int c = 0;
93        for(htmlNodePtr node = element; node != NULL; node = node->next)
94        {
95                gElement *child = add_element(node);
96                child->level = level;
97
98                if(elem) elem  = realloc(elem, sizeof(gElement*)*(c+1));
99                else elem = malloc(sizeof(gElement*));
100
101
102                elem[c] = child;
103
104                c++;
105
106                if(node->type == XML_ELEMENT_NODE)
107                {
108                        if(node->children != NULL) {
109                                explore(child->children,
110                                                node->children,
111                                                level+1,
112                                                child);
113                        } else {
114                                free(child->children);
115                                child->children = NULL;
116                        }
117                }         
118                if(parent) {
119                        parent->children = realloc(parent->children, sizeof(gElement*)*(parent->children_count+1));
120                        parent->children[parent->children_count] = child;
121                        parent->children_count++;
122                }
123        }
124        return *elem;
125}
126
127
128#define LEVEL {unsigned int foo=0; for(foo=0; foo<elem->level; foo++) printf("    ");}
129
130void pretty_print(gElement *elem) {
131        if(!elem) {
132                printf("elem is %p\n", elem);
133                return;
134        }
135
136        if(elem->type == ELEM_TEXT) {
137                LEVEL printf("%s\n", elem->text);
138        } else {
139                LEVEL printf("<%s", elem->name);
140        unsigned int a;
141        for(a = 0; a < elem->attribute_count; a++) {
142                printf(" %s=\"%s\"", elem->attributes[a].name, elem->attributes[a].value); 
143        }
144        printf(">\n");
145        }
146
147        unsigned int i;
148        for(i=0; i < elem->children_count; i++) {
149                pretty_print(elem->children[i]);
150        }
151
152        if(elem->type == ELEM_TEXT) {
153
154        } else {
155                LEVEL printf("</%s>\n", elem->name);
156        }
157}
158
Note: See TracBrowser for help on using the repository browser.