void ThingTypeManager::loadXml(const std::string& file)
{
    try {
        if(!isOtbLoaded())
            stdext::throw_exception("OTB must be loaded before XML");

        TiXmlDocument doc;
        doc.Parse(g_resources.readFileContents(file).c_str());
        if(doc.Error())
            stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc()));

        TiXmlElement* root = doc.FirstChildElement();
        if(!root || root->ValueTStr() != "items")
            stdext::throw_exception("invalid root tag name");

        for(TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) {
            if(unlikely(element->ValueTStr() != "item"))
                continue;

            uint16 id = element->readType<uint16>("id");
            if(id != 0) {
                std::vector<std::string> s_ids = stdext::split(element->Attribute("id"), ";");
                for(const std::string& s : s_ids) {
                    std::vector<int32> ids = stdext::split<int32>(s, "-");
                    if(ids.size() > 1) {
                        int32 i = ids[0];
                        while(i <= ids[1])
                            parseItemType(i++, element);
                    } else
                        parseItemType(atoi(s.c_str()), element);
                }
            } else {
                std::vector<int32> begin = stdext::split<int32>(element->Attribute("fromid"), ";");
                std::vector<int32> end   = stdext::split<int32>(element->Attribute("toid"), ";");
                if(begin[0] && begin.size() == end.size()) {
                    size_t size = begin.size();
                    for(size_t i = 0; i < size; ++i)
                        while(begin[i] <= end[i])
                            parseItemType(begin[i]++, element);
                }
            }
        }

        doc.Clear();
        m_xmlLoaded = true;
        g_logger.debug("items.xml read successfully.");
    } catch(std::exception& e) {
        g_logger.error(stdext::format("Failed to load '%s' (XML file): %s", file, e.what()));
    }
}
void ThingTypeManager::loadXml(const std::string& file)
{
    /// Read XML
    TiXmlDocument doc;
    doc.Parse(g_resources.loadFile(file).c_str());
    if(doc.Error())
        stdext::throw_exception(stdext::format("failed to parse '%s': '%s'", file, doc.ErrorDesc()));

    TiXmlElement* root = doc.FirstChildElement();
    if(!root || root->ValueTStr() != "items")
        stdext::throw_exception("invalid root tag name");

    for (TiXmlElement *element = root->FirstChildElement(); element; element = element->NextSiblingElement()) {
        if(element->ValueTStr() != "item")
            continue;

        uint16 id = element->readType<uint16>("id");
        if(id > 20000 && id < 20100) {
            id -= 20000;
            ItemTypePtr newType(new ItemType);
            newType->setServerId(id);
            addItemType(newType);
        }

        if(id != 0)
            parseItemType(id, element);
        else {
            uint16 fromId = element->readType<uint16>("fromid"), toId = element->readType<uint16>("toid");
            for(uint16 i = fromId; i < toId; ++i)
                parseItemType(i, element);
        }
    }

    doc.Clear();
    m_xmlLoaded = true;
    g_logger.debug("items.xml read successfully.");
}