get_{bool,int} reads childen node
[metaproxy-moved-to-github.git] / src / xmlutil.cpp
1 /* This file is part of Metaproxy.
2    Copyright (C) 2005-2011 Index Data
3
4 Metaproxy is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 #include <metaproxy/xmlutil.hpp>
20
21 #include <string.h>
22
23
24 namespace mp = metaproxy_1;
25 // Doxygen doesn't like mp::xml, so we use this instead
26 namespace mp_xml = metaproxy_1::xml;
27
28 static const std::string metaproxy_ns = "http://indexdata.com/metaproxy";
29
30 std::string mp_xml::get_text(const struct _xmlAttr  *ptr)
31 {
32     return get_text(ptr->children);
33 }
34
35 std::string mp_xml::get_text(const xmlNode *ptr)
36 {
37     std::string c;
38     if (ptr && ptr->type != XML_TEXT_NODE)
39         ptr = ptr->children;
40     for (; ptr; ptr = ptr->next)
41         if (ptr->type == XML_TEXT_NODE)
42             c += std::string((const char *) (ptr->content));
43     return c;
44 }
45
46 bool mp_xml::get_bool(const xmlNode *ptr, bool default_value)
47 {
48     if (ptr && ptr->type != XML_TEXT_NODE)
49         ptr = ptr->children;
50     if (ptr && ptr->type == XML_TEXT_NODE && ptr->content)
51     {
52         if (!strcmp((const char *) ptr->content, "true")
53             || !strcmp((const char *) ptr->content, "1"))
54             return true;
55         else
56             return false;
57     }
58     return default_value;
59 }
60
61 int mp_xml::get_int(const xmlNode *ptr, int default_value)
62
63     if (ptr && ptr->type != XML_TEXT_NODE)
64         ptr = ptr->children;
65     if (ptr && ptr->type == XML_TEXT_NODE && ptr->content)
66     {
67         return atoi((const char *) ptr->content);
68     }
69     return default_value;
70 }
71
72 bool mp_xml::check_attribute(const _xmlAttr *ptr, 
73                              const std::string &ns,
74                              const std::string &name)
75 {
76
77     if (!mp::xml::is_attribute(ptr, ns, name))
78     {   
79         std::string got_attr = "'";
80         if (ptr && ptr->name)
81             got_attr += std::string((const char *)ptr->name);
82         if (ns.size() && ptr && ptr->ns && ptr->ns->href){
83             got_attr += " ";
84             got_attr += std::string((const char *)ptr->ns->href);
85          }
86         got_attr += "'";
87         
88         throw mp::XMLError("Expected XML attribute '" + name 
89                            + " " + ns + "'"
90                            + ", not " + got_attr);
91     }
92     return true;
93 }
94
95 bool mp_xml::is_attribute(const _xmlAttr *ptr, 
96                           const std::string &ns,
97                           const std::string &name)
98 {
99     if (0 != xmlStrcmp(BAD_CAST name.c_str(), ptr->name))
100         return false;
101
102     if (ns.size() 
103         && (!ptr->ns || !ptr->ns->href 
104             || 0 != xmlStrcmp(BAD_CAST ns.c_str(), ptr->ns->href)))
105         return false;
106
107     return true;
108 }
109
110
111 bool mp_xml::is_element(const xmlNode *ptr, 
112                           const std::string &ns,
113                           const std::string &name)
114 {
115     if (ptr && ptr->type == XML_ELEMENT_NODE && ptr->ns && ptr->ns->href 
116         && !xmlStrcmp(BAD_CAST ns.c_str(), ptr->ns->href)
117         && !xmlStrcmp(BAD_CAST name.c_str(), ptr->name))
118         return true;
119     return false;
120 }
121
122 bool mp_xml::is_element_mp(const xmlNode *ptr, 
123                            const std::string &name)
124 {
125     return mp::xml::is_element(ptr, metaproxy_ns, name);
126 }
127
128
129 bool mp_xml::check_element_mp(const xmlNode *ptr, 
130                               const std::string &name)
131 {
132     if (!mp::xml::is_element_mp(ptr, name))
133     {
134         std::string got_element = "<";
135         if (ptr && ptr->name)
136             got_element += std::string((const char *)ptr->name);
137         if (ptr && ptr->ns && ptr->ns->href){
138             got_element += " xmlns=\"";
139             got_element += std::string((const char *)ptr->ns->href);
140             got_element += "\"";
141         }
142         got_element += ">";
143
144         throw mp::XMLError("Expected XML element <" + name 
145                            + " xmlns=\"" + metaproxy_ns + "\">"
146                            + ", not " + got_element);
147     }
148     return true;
149 }
150
151 std::string mp_xml::get_route(const xmlNode *node)
152 {
153     std::string route_value;
154     if (node)
155     {
156         const struct _xmlAttr *attr;
157         for (attr = node->properties; attr; attr = attr->next)
158         {
159             std::string name = std::string((const char *) attr->name);
160             std::string value;
161             
162             if (attr->children && attr->children->type == XML_TEXT_NODE)
163                 value = std::string((const char *)attr->children->content);
164             
165             if (name == "route")
166                 route_value = value;
167             else
168                 throw XMLError("Only attribute route allowed"
169                                " in " + std::string((const char *)node->name)
170                                + " element. Got " + std::string(name));
171         }
172     }
173     return route_value;
174 }
175
176
177 const xmlNode* mp_xml::jump_to_children(const xmlNode* node,
178                                           int xml_node_type)
179 {
180     node = node->children;
181     for (; node && node->type != xml_node_type; node = node->next)
182         ;
183     return node;
184 }
185
186 const xmlNode* mp_xml::jump_to_next(const xmlNode* node,
187                                       int xml_node_type)
188 {
189     node = node->next;
190     for (; node && node->type != xml_node_type; node = node->next)
191         ;
192     return node;
193 }
194
195 const xmlNode* mp_xml::jump_to(const xmlNode* node,
196                                  int xml_node_type)
197 {
198     for (; node && node->type != xml_node_type; node = node->next)
199         ;
200     return node;
201 }
202
203 void mp_xml::check_empty(const xmlNode *node)
204 {
205     if (node)
206     {
207         const xmlNode *n;
208         for (n = node->children; n; n = n->next)
209             if (n->type == XML_ELEMENT_NODE)
210                 throw mp::XMLError("No child elements allowed inside element "
211                                     + std::string((const char *) node->name));
212     }
213 }
214
215 /*
216  * Local variables:
217  * c-basic-offset: 4
218  * c-file-style: "Stroustrup"
219  * indent-tabs-mode: nil
220  * End:
221  * vim: shiftwidth=4 tabstop=8 expandtab
222  */
223