1 /* $Id: router_flexml.hpp,v 1.4 2005-10-28 10:35:30 marc Exp $
2 Copyright (c) 2005, Index Data.
10 //#include <stdexcept>
14 #include <libxml/xmlversion.h>
15 #include <libxml/parser.h>
16 #include <libxml/tree.h>
17 //#include <libxml/xmlIO.h>
18 //#include <libxml/xmlreader.h>
19 //#include <libxslt/transform.h>
21 #include <boost/shared_ptr.hpp>
28 class RouterFleXML : public yp2::Router
31 RouterFleXML(std::string xmlconf)
32 : m_xmlconf(""), m_xinclude(false), m_xmlconf_doc(0)
40 = xmlParseMemory(m_xmlconf.c_str(), m_xmlconf.size());
42 parse_xml_config_dom();
43 //parse_xml_config_xmlreader();
48 xmlFreeDoc(m_xmlconf_doc);
53 typedef std::map<std::string, boost::shared_ptr<const yp2::filter::Base> >
55 typedef std::list<std::string> FilterIdList;
56 typedef std::map<std::string, FilterIdList > IdRouteMap ;
60 std::string m_xmlconf;
62 xmlDoc * m_xmlconf_doc;
63 IdFilterMap m_id_filter_map;
64 FilterIdList m_filter_id_list;
65 IdRouteMap m_id_route_map;
67 //boost::shared_ptr<T> s_ptr(new T(t));
70 void xml_dom_error (const xmlNode* node, std::string msg)
72 std::cerr << "ERROR: " << msg << " <"
77 void create_filter(std::string type,
78 const xmlDoc * xmldoc,
81 std::cout << "Created Filter type='" << type
82 << "' id='" << id << "'" << std::endl;
86 void parse_xml_config_dom() {
87 //xmlNs *yp2_ns = xmlNewNs(pptr, BAD_CAST
88 // "http://indexdata.dk/yp2/config/1", 0);
94 const xmlNode* root = xmlDocGetRootElement(m_xmlconf_doc);
96 if ((std::string((const char *) root->name) != "yp2")
97 || (std::string((const char *)(root->ns->href))
98 != "http://indexdata.dk/yp2/config/1")
101 "expected <yp2 xmlns=\"http://indexdata.dk/yp2/config/1\">, got ");
104 for (const struct _xmlAttr *attr = root->properties; attr; attr = attr->next)
106 if (std::string((const char *)attr->name) == "xmlns")
108 const xmlNode *val = attr->children;
109 //BOOST_CHECK_EQUAL(val->type, XML_TEXT_NODE);
110 if (std::string((const char *)val->content)
111 != "http://indexdata.dk/yp2/config/1")
113 "expected xmlns=\"http://indexdata.dk/yp2/config/1\", got ");
116 std::cout << "processing /yp2" << std::endl;
118 // process <start> node which is expected first element node
119 const xmlNode* node = root->children;
120 for (; node && node->type != XML_ELEMENT_NODE; node = node->next)
122 if (std::string((const char *)node->name)
124 xml_dom_error(root, "expected <start>, got ");
126 std::cout << "processing /yp2/start" << std::endl;
128 // process <filters> node which is expected second element node
130 for (; node && node->type != XML_ELEMENT_NODE; node = node->next)
132 if (std::string((const char *)node->name)
134 xml_dom_error(root, "expected <filters>, got ");
136 std::cout << "processing /yp2/filters" << std::endl;
138 // process <filter> nodes in next level
139 const xmlNode* node2 = node->children;
140 for (; node2 && node2->type != XML_ELEMENT_NODE; node2 = node2->next)
142 if (std::string((const char *)node2->name)
144 xml_dom_error(root, "expected <filter>, got ");
146 while(node2 && std::string((const char *)node2->name) == "filter"){
147 std::cout << "processing /yp2/filters/filter" << std::endl;
148 for (; node2 && node2->type != XML_ELEMENT_NODE; node2 = node2->next)
149 std::cout << (const char *) root->name << std::endl;
150 if(node2->type != XML_ELEMENT_NODE)
154 // process <routes> node which is expected third element node
156 for (; node && node->type != XML_ELEMENT_NODE; node = node->next)
158 if (std::string((const char *)node->name)
160 xml_dom_error(root, "expected <routes>, got ");
162 std::cout << "processing /yp2/routes" << std::endl;
164 // process <route> nodes in next level
165 node2 = node->children;
166 for (; node2 && node2->type != XML_ELEMENT_NODE; node2 = node2->next)
168 if (std::string((const char *)node2->name)
170 xml_dom_error(root, "expected <route>, got ");
172 std::cout << "processing /yp2/routes/route" << std::endl;
174 // process <filter> nodes in third level
175 const xmlNode* node3 = node2->children;
176 for (; node3 && node3->type != XML_ELEMENT_NODE; node3 = node3->next)
178 if (std::string((const char *)node3->name)
180 xml_dom_error(root, "expected <filter>, got ");
182 std::cout << "processing /yp2/routes/route/filter" << std::endl;
189 void parse_xml_config_xmlreader() {
191 xmlTextReader* reader;
192 //reader->SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1);
194 //reader = xmlReaderForFile(m_xmlconf.c_str(), NULL, 0);
195 reader = xmlReaderWalker(m_xmlconf_doc);
197 if (reader == NULL) {
198 std::cerr << "failed to read XML config file "
200 << m_xmlconf << std::endl;
205 // root element processing
206 xml_progress_deep_to_element(reader);
207 if (std::string("yp2") != (const char*)xmlTextReaderConstName(reader))
208 xml_error(reader, "root element must be named <yp2>");
210 std::cout << "<" << xmlTextReaderConstName(reader);
212 //if (xmlTextReaderHasAttributes(reader))
213 //if ((!xmlTextReaderMoveToAttributeNs(reader, NULL,
214 // (const xmlChar*)"http://indexdata.dk/yp2/config/1" )))
215 if ((!xmlTextReaderMoveToFirstAttribute(reader))
216 || (! xmlTextReaderIsNamespaceDecl(reader))
217 || (std::string("http://indexdata.dk/yp2/config/1")
218 != (const char*)xmlTextReaderConstValue(reader)))
219 xml_error(reader, "expected root element <yp2> in namespace "
220 "'http://indexdata.dk/yp2/config/1'");
222 std::cout << " " << xmlTextReaderConstName(reader) << "=\""
223 << xmlTextReaderConstValue(reader) << "\">"
224 //<< xmlTextReaderIsNamespaceDecl(reader)
228 // start element processing
229 xml_progress_deep_to_element(reader);
230 if (std::string("start") != (const char*)xmlTextReaderConstName(reader)
231 || !xmlTextReaderMoveToFirstAttribute(reader)
232 || std::string("route") != (const char*)xmlTextReaderConstName(reader)
234 xml_error(reader, "start element <start route=\"route_id\"/> expected");
236 std::cout << "<start " << xmlTextReaderConstName(reader) << "=\""
237 << xmlTextReaderConstValue(reader) << "\"/>" << std::endl;
238 //<< xmlTextReaderGetAttribute(reader, (const xmlChar *)"route")
241 // filters element processing
242 xml_progress_flat_to_element(reader);
244 if (std::string("filters") != (const char*)xmlTextReaderConstName(reader)
246 xml_error(reader, "filters element <filters> expected");
248 std::cout << "<filters>" << std::endl;
251 // filter element processing
252 xml_progress_deep_to_element(reader);
253 if (std::string("filter") != (const char*)xmlTextReaderConstName(reader)
255 xml_error(reader, "filter element <filter id=\"some_id\" "
256 "type=\"some_type\"/> expected");
258 while (std::string("filter") == (const char*)xmlTextReaderConstName(reader)){
259 std::string filter_id;
260 std::string filter_type;
261 if (!xmlTextReaderMoveToFirstAttribute(reader)
262 || std::string("id") != (const char*)xmlTextReaderConstName(reader))
263 xml_error(reader, "filter element <filter id=\"some_id\" "
264 "type=\"some_type\"/> expected");
265 filter_id = (const char*)xmlTextReaderConstValue(reader);
266 if (!xmlTextReaderMoveToNextAttribute(reader)
267 || std::string("type") != (const char*)xmlTextReaderConstName(reader))
268 xml_error(reader, "filter element <filter id=\"some_id\" "
269 "type=\"some_type\"/> expected");
270 filter_type = (const char*)xmlTextReaderConstValue(reader);
271 std::cout << "<filter id=\"" << filter_id
272 << "\" type=\"" << filter_type << "\"/>"
274 xml_progress_flat_to_element(reader);
277 std::cout << "</filters>" << std::endl;
280 // routes element processing
281 // xml_progress_flat_to_element(reader);
282 if (std::string("routes") != (const char*)xmlTextReaderConstName(reader)
284 xml_error(reader, "routes element <routes> expected");
286 std::cout << "<routes>" << std::endl;
287 // route element processing
288 xml_progress_deep_to_element(reader);
289 if (std::string("route") != (const char*)xmlTextReaderConstName(reader)
291 xml_error(reader, "route element <route id=\"some_id\" "
292 "type=\"some_type\"/> expected");
293 while (std::string("route") == (const char*)xmlTextReaderConstName(reader)){
294 std::string route_id;
295 if (!xmlTextReaderMoveToFirstAttribute(reader)
296 || std::string("id") != (const char*)xmlTextReaderConstName(reader))
297 xml_error(reader, "route element <route id=\"some_id\"/> expected");
298 route_id = (const char*)xmlTextReaderConstValue(reader);
301 std::cout << "<route id=\"" << route_id << "\">" << std::endl;
302 std::cout << "</route>" << std::endl;
303 xml_progress_flat_to_element(reader);
306 std::cout << "</routes>" << std::endl;
308 std::cout << "</yp2>" << std::endl;
310 xml_debug_print(reader);
313 // freeing C xml reader libs
314 xmlFreeTextReader(reader);
316 std::cerr << "Parsing failed of XML configuration"
318 << m_xmlconf << std::endl;
323 void xml_error ( xmlTextReader* reader, std::string msg)
325 std::cerr << "ERROR: " << msg << " "
326 << xmlTextReaderGetParserLineNumber(reader) << ":"
327 << xmlTextReaderGetParserColumnNumber(reader) << " "
328 << xmlTextReaderConstName(reader) << " "
329 << xmlTextReaderDepth(reader) << " "
330 << xmlTextReaderNodeType(reader) << std::endl;
333 void xml_debug_print ( xmlTextReader* reader)
335 // processing all other elements
336 //while (xmlTextReaderMoveToElement(reader)) // reads next element ??
337 //while (xmlTextReaderNext(reader)) //does not descend, keeps level
338 while (xmlTextReaderRead(reader)) // descends into all subtree nodes
339 std::cout << xmlTextReaderGetParserLineNumber(reader) << ":"
340 << xmlTextReaderGetParserColumnNumber(reader) << " "
341 << xmlTextReaderDepth(reader) << " "
342 << xmlTextReaderNodeType(reader) << " "
343 << "ConstName " << xmlTextReaderConstName(reader) << " "
347 bool xml_progress_deep_to_element(xmlTextReader* reader)
350 while(xmlTextReaderRead(reader)
351 && xmlTextReaderNodeType(reader) != XML_ELEMENT_NODE
352 && !( xmlTextReaderNodeType(reader)
353 == XML_READER_TYPE_END_ELEMENT
354 && 0 == xmlTextReaderDepth(reader))
360 bool xml_progress_flat_to_element(xmlTextReader* reader)
364 while(xmlTextReaderNext(reader)
365 && xmlTextReaderNodeType(reader) != XML_ELEMENT_NODE
366 && !( xmlTextReaderNodeType(reader)
367 == XML_READER_TYPE_END_ELEMENT
368 && 0 == xmlTextReaderDepth(reader))
385 * indent-tabs-mode: nil
386 * c-file-style: "stroustrup"
388 * vim: shiftwidth=4 tabstop=8 expandtab