2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 #include <libxml/parser.h>
21 #include <libxml/tree.h>
24 typedef struct private_xml_t private_xml_t
;
29 struct private_xml_t
{
37 * root node of this xml (part)
42 * document, only for root xml_t
52 * number of enumerator instances
58 * child element enumerator
61 /** enumerator interface */
63 /** current child context (returned to enumerate() caller) */
65 /** currently processing node */
70 * Implementation of xml_t.children().enumerate().
72 static bool child_enumerate(child_enum_t
*e
, private_xml_t
**child
,
73 char **name
, char **value
)
75 while (e
->node
&& e
->node
->type
!= XML_ELEMENT_NODE
)
77 e
->node
= e
->node
->next
;
83 text
= e
->node
->children
;
86 while (text
&& text
->type
!= XML_TEXT_NODE
)
92 *value
= text
->content
;
94 *name
= (char*)e
->node
->name
;
96 e
->child
.node
= e
->node
->children
;
97 e
->node
= e
->node
->next
;
104 * Implementation of xml_t.get_attribute.
106 static char* get_attribute(private_xml_t
*this, char *name
)
112 * destroy enumerator, and complete tree if this was the last enumerator
114 static void child_destroy(child_enum_t
*this)
116 if (--this->child
.root
->enums
== 0)
118 xmlFreeDoc(this->child
.root
->doc
);
119 free(this->child
.root
);
125 * Implementation of xml_t.children.
127 static enumerator_t
* children(private_xml_t
*this)
129 child_enum_t
*ce
= malloc_thing(child_enum_t
);
130 ce
->e
.enumerate
= (void*)child_enumerate
;
131 ce
->e
.destroy
= (void*)child_destroy
;
132 ce
->node
= this->node
;
133 ce
->child
.public.children
= (void*)children
;
134 ce
->child
.public.get_attribute
= (void*)get_attribute
;
135 ce
->child
.node
= NULL
;
136 ce
->child
.doc
= this->doc
;
137 ce
->child
.root
= this->root
;
145 xml_t
*xml_create(char *xml
)
147 private_xml_t
*this = malloc_thing(private_xml_t
);
149 this->public.get_attribute
= (char*(*)(xml_t
*,char*))get_attribute
;
150 this->public.children
= (enumerator_t
*(*)(xml_t
*))children
;
152 this->doc
= xmlReadMemory(xml
, strlen(xml
), NULL
, NULL
, 0);
153 if (this->doc
== NULL
)
158 this->node
= xmlDocGetRootElement(this->doc
);
162 return &this->public;