/* * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See . * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include #include "xml.h" #include #include typedef struct private_xml_t private_xml_t; /** * private data of xml */ struct private_xml_t { /** * public functions */ xml_t public; /** * root node of this xml (part) */ xmlNode *node; /** * document, only for root xml_t */ xmlDoc *doc; /** * Root xml_t* */ private_xml_t *root; /** * number of enumerator instances */ int enums; }; /** * child element enumerator */ typedef struct { /** enumerator interface */ enumerator_t e; /** current child context (returned to enumerate() caller) */ private_xml_t child; /** currently processing node */ xmlNode *node; } child_enum_t; METHOD(enumerator_t, child_enumerate, bool, child_enum_t *e, va_list args) { private_xml_t **child; char **name, **value; VA_ARGS_VGET(args, child, name, value); while (e->node && e->node->type != XML_ELEMENT_NODE) { e->node = e->node->next; } if (e->node) { xmlNode *text; text = e->node->children; *value = NULL; while (text && text->type != XML_TEXT_NODE) { text = text->next; } if (text) { *value = text->content; } *name = (char*)e->node->name; *child = &e->child; e->child.node = e->node->children; e->node = e->node->next; return TRUE; } return FALSE; } METHOD(xml_t, get_attribute, char*, private_xml_t *this, char *name) { return NULL; } METHOD(enumerator_t, child_destroy, void, child_enum_t *this) { if (--this->child.root->enums == 0) { xmlFreeDoc(this->child.root->doc); free(this->child.root); } free(this); } METHOD(xml_t, children, enumerator_t*, private_xml_t *this) { child_enum_t *ce; INIT(ce, .e = { .enumerate = enumerator_enumerate_default, .venumerate = _child_enumerate, .destroy = _child_destroy, }, .child = { .public = { .get_attribute = _get_attribute, .children = _children, }, .doc = this->doc, .root = this->root, }, .node = this->node, ); this->root->enums++; return &ce->e; } /* * see header file */ xml_t *xml_create(char *xml) { private_xml_t *this; INIT(this, .public = { .get_attribute = _get_attribute, .children = _children, }, .doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0), ); if (!this->doc) { free(this); return NULL; } this->node = xmlDocGetRootElement(this->doc); this->root = this; return &this->public; }