void XMLResourceDocument::load(IODevice file, const std::string &base_path, const FileSystem &fs) { DomDocument new_document; new_document.load(file); // Check if loaded document uses namespaces and if its a clanlib resources xml document: DomElement doc_element = new_document.get_document_element(); if (doc_element.get_namespace_uri().empty() && doc_element.get_local_name() == "resources") { impl->ns_resources = std::string(); } else if (doc_element.get_namespace_uri() == "http://clanlib.org/xmlns/resources-1.0") { if (doc_element.get_local_name() != "resources") throw Exception("ClanLib resource documents must begin with a resources element."); impl->ns_resources = "http://clanlib.org/xmlns/resources-1.0"; } else { throw Exception("XML document is not a ClanLib resources document."); } impl->document = new_document; impl->fs = fs; impl->base_path = base_path; impl->resources.clear(); std::vector<std::string> section_stack; std::vector<DomNode> nodes_stack; section_stack.push_back(std::string()); nodes_stack.push_back(doc_element.get_first_child()); while (!nodes_stack.empty()) { if (nodes_stack.back().is_element()) { DomElement element = nodes_stack.back().to_element(); if (element.get_namespace_uri() == impl->ns_resources && element.get_local_name() == "section") { std::string section_name = element.get_attribute_ns(impl->ns_resources, "name"); section_stack.push_back(section_stack.back() + PathHelp::add_trailing_slash(section_name, PathHelp::path_type_virtual)); nodes_stack.push_back(element.get_first_child()); continue; } else if (element.has_attribute_ns(impl->ns_resources, "name")) { std::string resource_name = element.get_attribute_ns(impl->ns_resources, "name"); std::string resource_id = section_stack.back() + resource_name; impl->resources[resource_id] = XMLResourceNode(element, *this); } } nodes_stack.back() = nodes_stack.back().get_next_sibling(); while (nodes_stack.back().is_null()) { nodes_stack.pop_back(); section_stack.pop_back(); if (nodes_stack.empty()) break; nodes_stack.back() = nodes_stack.back().get_next_sibling(); } } }