f211fc4c19664e65b85906472a6aa50f69cec892
[metaproxy-moved-to-github.git] / src / xmlutil.cpp
1 /* This file is part of Metaproxy.
2    Copyright (C) 2005-2008 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 "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 && ptr->content)
49     {
50         if (!strcmp((const char *) ptr->content, "true"))
51             return true;
52         else
53             return false;
54     }
55     return default_value;
56 }
57
58 int mp_xml::get_int(const xmlNode *ptr, int default_value)
59 {
60     if (ptr && ptr->type == XML_TEXT_NODE && ptr->content)
61     {
62         return atoi((const char *) ptr->content);
63     }
64     return default_value;
65 }
66
67 bool mp_xml::check_attribute(const _xmlAttr *ptr, 
68                              const std::string &ns,
69                              const std::string &name)
70 {
71
72     if (!mp::xml::is_attribute(ptr, ns, name))
73     {   
74         std::string got_attr = "'";
75         if (ptr && ptr->name)
76             got_attr += std::string((const char *)ptr->name);
77         if (ns.size() && ptr && ptr->ns && ptr->ns->href){
78             got_attr += " ";
79             got_attr += std::string((const char *)ptr->ns->href);
80          }
81         got_attr += "'";
82         
83         throw mp::XMLError("Expected XML attribute '" + name 
84                            + " " + ns + "'"
85                            + ", not " + got_attr);
86     }
87     return true;
88 }
89
90 bool mp_xml::is_attribute(const _xmlAttr *ptr, 
91                           const std::string &ns,
92                           const std::string &name)
93 {
94     if (0 != xmlStrcmp(BAD_CAST name.c_str(), ptr->name))
95         return false;
96
97     if (ns.size() 
98         && (!ptr->ns || !ptr->ns->href 
99             || 0 != xmlStrcmp(BAD_CAST ns.c_str(), ptr->ns->href)))
100         return false;
101
102     return true;
103 }
104
105
106 bool mp_xml::is_element(const xmlNode *ptr, 
107                           const std::string &ns,
108                           const std::string &name)
109 {
110     if (ptr && ptr->type == XML_ELEMENT_NODE && ptr->ns && ptr->ns->href 
111         && !xmlStrcmp(BAD_CAST ns.c_str(), ptr->ns->href)
112         && !xmlStrcmp(BAD_CAST name.c_str(), ptr->name))
113         return true;
114     return false;
115 }
116
117 bool mp_xml::is_element_mp(const xmlNode *ptr, 
118                            const std::string &name)
119 {
120     return mp::xml::is_element(ptr, metaproxy_ns, name);
121 }
122
123
124 bool mp_xml::check_element_mp(const xmlNode *ptr, 
125                               const std::string &name)
126 {
127     if (!mp::xml::is_element_mp(ptr, name))
128     {
129         std::string got_element = "<";
130         if (ptr && ptr->name)
131             got_element += std::string((const char *)ptr->name);
132         if (ptr && ptr->ns && ptr->ns->href){
133             got_element += " xmlns=\"";
134             got_element += std::string((const char *)ptr->ns->href);
135             got_element += "\"";
136         }
137         got_element += ">";
138
139         throw mp::XMLError("Expected XML element <" + name 
140                            + " xmlns=\"" + metaproxy_ns + "\">"
141                            + ", not " + got_element);
142     }
143     return true;
144 }
145
146 std::string mp_xml::get_route(const xmlNode *node)
147 {
148     std::string route_value;
149     if (node)
150     {
151         const struct _xmlAttr *attr;
152         for (attr = node->properties; attr; attr = attr->next)
153         {
154             std::string name = std::string((const char *) attr->name);
155             std::string value;
156             
157             if (attr->children && attr->children->type == XML_TEXT_NODE)
158                 value = std::string((const char *)attr->children->content);
159             
160             if (name == "route")
161                 route_value = value;
162             else
163                 throw XMLError("Only attribute route allowed"
164                                " in " + std::string((const char *)node->name)
165                                + " element. Got " + std::string(name));
166         }
167     }
168     return route_value;
169 }
170
171
172 const xmlNode* mp_xml::jump_to_children(const xmlNode* node,
173                                           int xml_node_type)
174 {
175     node = node->children;
176     for (; node && node->type != xml_node_type; node = node->next)
177         ;
178     return node;
179 }
180
181 const xmlNode* mp_xml::jump_to_next(const xmlNode* node,
182                                       int xml_node_type)
183 {
184     node = node->next;
185     for (; node && node->type != xml_node_type; node = node->next)
186         ;
187     return node;
188 }
189
190 const xmlNode* mp_xml::jump_to(const xmlNode* node,
191                                  int xml_node_type)
192 {
193     for (; node && node->type != xml_node_type; node = node->next)
194         ;
195     return node;
196 }
197
198 void mp_xml::check_empty(const xmlNode *node)
199 {
200     if (node)
201     {
202         const xmlNode *n;
203         for (n = node->children; n; n = n->next)
204             if (n->type == XML_ELEMENT_NODE)
205                 throw mp::XMLError("No child elements allowed inside element "
206                                     + std::string((const char *) node->name));
207     }
208 }
209
210 /*
211  * Local variables:
212  * c-basic-offset: 4
213  * c-file-style: "Stroustrup"
214  * indent-tabs-mode: nil
215  * End:
216  * vim: shiftwidth=4 tabstop=8 expandtab
217  */
218