void LibxmlParser::parseXML(XMLHandler& handler,
                            const RawDataContainer& source,
                            const String& /*schemaName*/,
                            bool /*allowXmlValidation*/)
{
    xmlDocPtr doc = xmlParseMemory(
        reinterpret_cast<const char*>(source.getDataPtr()),
        source.getSize());

    if (!doc)
    {
        xmlError* err = xmlGetLastError();

        CEGUI_THROW(GenericException(
            String("xmlParseMemory failed in file: '") +
            err->file + "' at line number" +
            PropertyHelper<uint>::toString(err->line) + ".  Error is:" +
            err->message));
    }

    // get root element
    xmlNode* root = xmlDocGetRootElement(doc);

    // process all elements from root to end of doc
    processXMLElement(handler, root);

    // release the xmlDoc 
    xmlFreeDoc(doc);
}
void LibxmlParser::parseXMLFile(XMLHandler& handler, const String& filename, const String&, const String& resourceGroup)
{
    // load xml file data into buffer using resource provider
    CEGUI::RawDataContainer rawXMLData;
    CEGUI::System::getSingleton().getResourceProvider()->loadRawDataContainer(filename, rawXMLData, resourceGroup);

    xmlDocPtr doc = xmlParseMemory(
        reinterpret_cast<char*>(rawXMLData.getDataPtr()),
        rawXMLData.getSize());

    // release loaded xml data.
    System::getSingleton().getResourceProvider()->
        unloadRawDataContainer(rawXMLData);

    if (!doc)
    {
        xmlError* err = xmlGetLastError();

        throw GenericException(
            String("LibxmlParser::parseXMLFile - xmlParseMemory failed in file: '") +
            err->file + "' at line number" +
            PropertyHelper::uintToString(err->line) + ".  Error is:" +
            err->message);
    }

    // get root element
    xmlNode* root = xmlDocGetRootElement(doc);

    // process all elements from root to end of doc
    processXMLElement(handler, root);

    // release the xmlDoc 
    xmlFreeDoc(doc);
}
// internal helper function to process elements
void processXMLElement(XMLHandler& handler, xmlNode* node)
{
    // build attributes block for the element
    XMLAttributes attrs;

    xmlAttrPtr currAttr = node->properties;
    while (currAttr)
    {
        xmlChar* val = xmlGetProp(node, currAttr->name);
        attrs.add((utf8*)currAttr->name, (utf8*)val);
        xmlFree(val);
        currAttr = currAttr->next;
    }

    // element start processing
    handler.elementStart((utf8*)node->name, attrs);

    for (xmlNode* cur_node = node->children; cur_node; cur_node = cur_node->next)
    {
        switch(cur_node->type)
        {
        case XML_ELEMENT_NODE:
            processXMLElement(handler, cur_node);
            break;

        case XML_TEXT_NODE:
            if (cur_node->content != 0 && *cur_node->content!= '\0')
                handler.text((utf8*)cur_node->content);
            break;
        }
    }

    // element end processing
    handler.elementEnd((utf8*)node->name);
}