metaproxy  1.21.0
xmlutil.cpp
Go to the documentation of this file.
1 /* This file is part of Metaproxy.
2  Copyright (C) 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 "config.hpp"
20 
21 #include <metaproxy/xmlutil.hpp>
22 
23 #include <string.h>
24 
25 namespace mp = metaproxy_1;
26 // Doxygen doesn't like mp::xml, so we use this instead
27 namespace mp_xml = metaproxy_1::xml;
28 
29 static const std::string metaproxy_ns = "http://indexdata.com/metaproxy";
30 
31 std::string mp_xml::get_text(const struct _xmlAttr *ptr)
32 {
33  return get_text(ptr->children);
34 }
35 
36 std::string mp_xml::get_text(const xmlNode *ptr)
37 {
38  std::string c;
39  if (ptr && ptr->type != XML_TEXT_NODE)
40  ptr = ptr->children;
41  for (; ptr; ptr = ptr->next)
42  if (ptr->type == XML_TEXT_NODE)
43  c += std::string((const char *) (ptr->content));
44  return c;
45 }
46 
47 bool mp_xml::get_bool(const xmlNode *ptr, bool default_value)
48 {
49  if (ptr && ptr->type != XML_TEXT_NODE)
50  ptr = ptr->children;
51  if (ptr && ptr->type == XML_TEXT_NODE && ptr->content)
52  {
53  if (!strcmp((const char *) ptr->content, "true")
54  || !strcmp((const char *) ptr->content, "1"))
55  return true;
56  else
57  return false;
58  }
59  return default_value;
60 }
61 
62 int mp_xml::get_int(const xmlNode *ptr, int default_value)
63 {
64  if (ptr && ptr->type != XML_TEXT_NODE)
65  ptr = ptr->children;
66  if (ptr && ptr->type == XML_TEXT_NODE && ptr->content)
67  {
68  return atoi((const char *) ptr->content);
69  }
70  return default_value;
71 }
72 
73 bool mp_xml::check_attribute(const _xmlAttr *ptr,
74  const std::string &ns,
75  const std::string &name)
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 void mp_xml::parse_attr(const xmlNode *node, const char **names,
152  std::string *values)
153 {
154  size_t i;
155  for (i = 0; names[i]; i++)
156  values[i].clear();
157 
158  if (node)
159  {
160  const struct _xmlAttr *attr;
161  for (attr = node->properties; attr; attr = attr->next)
162  {
163  std::string value;
164  const char *name = (const char *) attr->name;
165 
166  if (attr->children && attr->children->type == XML_TEXT_NODE)
167  value = std::string((const char *)attr->children->content);
168  for (i = 0; names[i]; i++)
169  if (!strcmp(name, names[i]))
170  {
171  values[i] = value;
172  break;
173  }
174  if (!names[i])
175  {
176  throw XMLError("Unsupported attribute: '" +
177  std::string(name) +
178  "' in element '" +
179  std::string((const char *) node->name) + "'");
180  }
181  }
182  }
183 }
184 
185 std::string mp_xml::get_route(const xmlNode *node, std::string &auth)
186 {
187  const char *names[3] = { "route", "auth", 0 };
188  std::string values[2];
189 
190  parse_attr(node, names, values);
191 
192  auth = values[1];
193  return values[0];
194 }
195 
196 std::string mp_xml::get_route(const xmlNode *node)
197 {
198  const char *names[2] = { "route", 0 };
199  std::string values[1];
200 
201  parse_attr(node, names, values);
202 
203  return values[0];
204 }
205 
206 const xmlNode* mp_xml::jump_to_children(const xmlNode* node,
207  int xml_node_type)
208 {
209  node = node->children;
210  for (; node && node->type != xml_node_type; node = node->next)
211  ;
212  return node;
213 }
214 
215 const xmlNode* mp_xml::jump_to_next(const xmlNode* node,
216  int xml_node_type)
217 {
218  node = node->next;
219  for (; node && node->type != xml_node_type; node = node->next)
220  ;
221  return node;
222 }
223 
224 const xmlNode* mp_xml::jump_to(const xmlNode* node,
225  int xml_node_type)
226 {
227  for (; node && node->type != xml_node_type; node = node->next)
228  ;
229  return node;
230 }
231 
232 void mp_xml::check_empty(const xmlNode *node)
233 {
234  if (node)
235  {
236  const xmlNode *n;
237  const struct _xmlAttr *attr;
238  std::string extra;
239  for (attr = node->properties; attr; attr = attr->next)
240  if (!strcmp((const char *) attr->name, "type"))
241  extra = " of type " + get_text(attr);
242  for (n = node->children; n; n = n->next)
243  if (n->type == XML_ELEMENT_NODE)
244  throw mp::XMLError("No child elements allowed inside element "
245  + std::string((const char *) node->name)
246  + extra);
247  }
248 }
249 
250 /*
251  * Local variables:
252  * c-basic-offset: 4
253  * c-file-style: "Stroustrup"
254  * indent-tabs-mode: nil
255  * End:
256  * vim: shiftwidth=4 tabstop=8 expandtab
257  */
258 
static const std::string metaproxy_ns
Definition: xmlutil.cpp:29