Year 2007.
[metaproxy-moved-to-github.git] / src / xmlutil.cpp
1 /* $Id: xmlutil.cpp,v 1.13 2007-01-25 14:05:54 adam Exp $
2    Copyright (c) 2005-2007, Index Data.
3
4    See the LICENSE file for details
5  */
6
7 #include "xmlutil.hpp"
8
9 #include <string.h>
10
11
12 namespace mp = metaproxy_1;
13 // Doxygen doesn't like mp::xml, so we use this instead
14 namespace mp_xml = metaproxy_1::xml;
15
16 static const std::string metaproxy_ns = "http://indexdata.com/metaproxy";
17
18 std::string mp_xml::get_text(const struct _xmlAttr  *ptr)
19 {
20     return get_text(ptr->children);
21 }
22
23 std::string mp_xml::get_text(const xmlNode *ptr)
24 {
25     std::string c;
26     if (ptr && ptr->type != XML_TEXT_NODE)
27         ptr = ptr->children;
28     for (; ptr; ptr = ptr->next)
29         if (ptr->type == XML_TEXT_NODE)
30             c += std::string((const char *) (ptr->content));
31     return c;
32 }
33
34 bool mp_xml::get_bool(const xmlNode *ptr, bool default_value)
35 {
36     if (ptr && ptr->type == XML_TEXT_NODE && ptr->content)
37     {
38         if (!strcmp((const char *) ptr->content, "true"))
39             return true;
40         else
41             return false;
42     }
43     return default_value;
44 }
45
46 int mp_xml::get_int(const xmlNode *ptr, int default_value)
47 {
48     if (ptr && ptr->type == XML_TEXT_NODE && ptr->content)
49     {
50         return atoi((const char *) ptr->content);
51     }
52     return default_value;
53 }
54
55 bool mp_xml::check_attribute(const _xmlAttr *ptr, 
56                              const std::string &ns,
57                              const std::string &name)
58 {
59
60     if (!mp::xml::is_attribute(ptr, ns, name))
61     {   
62         std::string got_attr = "'";
63         if (ptr && ptr->name)
64             got_attr += std::string((const char *)ptr->name);
65         if (ns.size() && ptr && ptr->ns && ptr->ns->href){
66             got_attr += " ";
67             got_attr += std::string((const char *)ptr->ns->href);
68          }
69         got_attr += "'";
70         
71         throw mp::XMLError("Expected XML attribute '" + name 
72                            + " " + ns + "'"
73                            + ", not " + got_attr);
74     }
75     return true;
76 }
77
78 bool mp_xml::is_attribute(const _xmlAttr *ptr, 
79                           const std::string &ns,
80                           const std::string &name)
81 {
82     if (0 != xmlStrcmp(BAD_CAST name.c_str(), ptr->name))
83         return false;
84
85     if (ns.size() 
86         && (!ptr->ns || !ptr->ns->href 
87             || 0 != xmlStrcmp(BAD_CAST ns.c_str(), ptr->ns->href)))
88         return false;
89
90     return true;
91 }
92
93
94 bool mp_xml::is_element(const xmlNode *ptr, 
95                           const std::string &ns,
96                           const std::string &name)
97 {
98     if (ptr && ptr->type == XML_ELEMENT_NODE && ptr->ns && ptr->ns->href 
99         && !xmlStrcmp(BAD_CAST ns.c_str(), ptr->ns->href)
100         && !xmlStrcmp(BAD_CAST name.c_str(), ptr->name))
101         return true;
102     return false;
103 }
104
105 bool mp_xml::is_element_mp(const xmlNode *ptr, 
106                            const std::string &name)
107 {
108     return mp::xml::is_element(ptr, metaproxy_ns, name);
109 }
110
111
112 bool mp_xml::check_element_mp(const xmlNode *ptr, 
113                               const std::string &name)
114 {
115     if (!mp::xml::is_element_mp(ptr, name))
116     {
117         std::string got_element = "<";
118         if (ptr && ptr->name)
119             got_element += std::string((const char *)ptr->name);
120         if (ptr && ptr->ns && ptr->ns->href){
121             got_element += " xmlns=\"";
122             got_element += std::string((const char *)ptr->ns->href);
123             got_element += "\"";
124         }
125         got_element += ">";
126
127         throw mp::XMLError("Expected XML element <" + name 
128                            + " xmlns=\"" + metaproxy_ns + "\">"
129                            + ", not " + got_element);
130     }
131     return true;
132 }
133
134 std::string mp_xml::get_route(const xmlNode *node)
135 {
136     std::string route_value;
137     if (node)
138     {
139         const struct _xmlAttr *attr;
140         for (attr = node->properties; attr; attr = attr->next)
141         {
142             std::string name = std::string((const char *) attr->name);
143             std::string value;
144             
145             if (attr->children && attr->children->type == XML_TEXT_NODE)
146                 value = std::string((const char *)attr->children->content);
147             
148             if (name == "route")
149                 route_value = value;
150             else
151                 throw XMLError("Only attribute route allowed"
152                                " in " + std::string((const char *)node->name)
153                                + " element. Got " + std::string(name));
154         }
155     }
156     return route_value;
157 }
158
159
160 const xmlNode* mp_xml::jump_to_children(const xmlNode* node,
161                                           int xml_node_type)
162 {
163     node = node->children;
164     for (; node && node->type != xml_node_type; node = node->next)
165         ;
166     return node;
167 }
168
169 const xmlNode* mp_xml::jump_to_next(const xmlNode* node,
170                                       int xml_node_type)
171 {
172     node = node->next;
173     for (; node && node->type != xml_node_type; node = node->next)
174         ;
175     return node;
176 }
177
178 const xmlNode* mp_xml::jump_to(const xmlNode* node,
179                                  int xml_node_type)
180 {
181     for (; node && node->type != xml_node_type; node = node->next)
182         ;
183     return node;
184 }
185
186 void mp_xml::check_empty(const xmlNode *node)
187 {
188     if (node)
189     {
190         const xmlNode *n;
191         for (n = node->children; n; n = n->next)
192             if (n->type == XML_ELEMENT_NODE)
193                 throw mp::XMLError("No child elements allowed inside element "
194                                     + std::string((const char *) node->name));
195     }
196 }
197
198 /*
199  * Local variables:
200  * c-basic-offset: 4
201  * indent-tabs-mode: nil
202  * c-file-style: "stroustrup"
203  * End:
204  * vim: shiftwidth=4 tabstop=8 expandtab
205  */