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