1 //Copyright (c) 2020 Ultimaker B.V.
2 //libSavitar is released under the terms of the AGPLv3 or higher.
3 
4 #include "Namespace.h"
5 
6 #include <pugixml.hpp>
7 
8 namespace xml_namespace
9 {
getCuraUri()10     std::string getCuraUri() { return std::string("http://software.ultimaker.com/xml/cura/3mf/2015/10"); }
getDefaultUri()11     std::string getDefaultUri() { return std::string("http://schemas.microsoft.com/3dmanufacturing/core/2015/02"); }
12 
appendNamespaceAttributes(xmlns_map_t & map,std::set<std::string> & namespace_names,const pugi::xml_node & xml_node)13     void appendNamespaceAttributes(xmlns_map_t& map, std::set<std::string>& namespace_names, const pugi::xml_node& xml_node)
14     {
15         for (const pugi::xml_attribute& attribute : xml_node.attributes())
16         {
17             const std::string name = attribute.name();
18             const std::string name_start = name.substr(0, name.size() >= 5 ? 5 : std::string::npos);
19             if (name_start.compare("xmlns") != 0)
20             {
21                 continue;
22             }
23 
24             const std::string namespace_name = name.size() <= 5 ? "" : name.substr(6);
25             const std::string namespace_glob = attribute.value();
26             if (namespace_names.count(namespace_name) > 0) // <-- check for overwrites
27             {
28                 continue; // <-- since it's going up the tree from the node, not down from the parent
29             }
30             if (map.count(namespace_glob) < 1)
31             {
32                 map[namespace_glob] = std::set<std::string>();
33             }
34             map[namespace_glob].insert(namespace_name);
35             namespace_names.insert(namespace_name);
36         }
37     }
38 
getAncestralNamespaces(const pugi::xml_node & xml_node)39     xmlns_map_t getAncestralNamespaces(const pugi::xml_node& xml_node)
40     {
41         xmlns_map_t result;
42         std::set<std::string> namespace_names;
43         for (pugi::xml_node current_node = xml_node; current_node; current_node = current_node.parent())
44         {
45             appendNamespaceAttributes(result, namespace_names, current_node);
46         }
47         return result;
48     }
49 
getNamesFor(const xmlns_map_t & map,const std::string & uri)50     std::set<std::string> getNamesFor(const xmlns_map_t& map, const std::string& uri)
51     {
52         return (map.count(uri) > 0) ? map.at(uri) : std::set<std::string>();
53     }
54 
55 } //namespace xml_namespace
56