1 /* $Id: router_flexml.hpp,v 1.2 2005-10-26 21:30:54 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() {
89 const xmlNode* root = xmlDocGetRootElement(m_xmlconf_doc);
91 if (std::string((const char *) root->name) != "yp2")
92 xml_dom_error(root, "expected <yp2>, got ");
95 for (const struct _xmlAttr *attr = root->properties; attr; attr = attr->next)
97 if (std::string((const char *)attr->name) == "xmlns")
99 const xmlNode *val = attr->children;
100 //BOOST_CHECK_EQUAL(val->type, XML_TEXT_NODE);
101 if (std::string((const char *)val->content)
102 != "http://indexdata.dk/yp2/config/1")
104 "expected xmlns=\"http://indexdata.dk/yp2/config/1\", got ");
107 std::cout << "processing /yp2" << std::endl;
109 // process <start> node which is expected first element node
110 const xmlNode* node = root->children;
111 for (; node && node->type != XML_ELEMENT_NODE; node = node->next)
113 if (std::string((const char *)node->name)
115 xml_dom_error(root, "expected <start>, got ");
117 std::cout << "processing /yp2/start" << std::endl;
119 // process <filters> node which is expected second element node
121 for (; node && node->type != XML_ELEMENT_NODE; node = node->next)
123 if (std::string((const char *)node->name)
125 xml_dom_error(root, "expected <filters>, got ");
127 std::cout << "processing /yp2/filters" << std::endl;
129 // process <filter> nodes in next level
130 const xmlNode* node2 = node->children;
131 for (; node2 && node2->type != XML_ELEMENT_NODE; node2 = node2->next)
133 if (std::string((const char *)node2->name)
135 xml_dom_error(root, "expected <filter>, got ");
137 //while(node2 && std::string((const char *)node2->name) == "filter"){
138 std::cout << "processing /yp2/filters/filter" << std::endl;
139 //for (; node2 && node2->type != XML_ELEMENT_NODE; node2 = node2->next)
141 //if(node2->type != XML_ELEMENT_NODE)
145 // process <routes> node which is expected third element node
147 for (; node && node->type != XML_ELEMENT_NODE; node = node->next)
149 if (std::string((const char *)node->name)
151 xml_dom_error(root, "expected <routes>, got ");
153 std::cout << "processing /yp2/routes" << std::endl;
155 // process <route> nodes in next level
156 node2 = node->children;
157 for (; node2 && node2->type != XML_ELEMENT_NODE; node2 = node2->next)
159 if (std::string((const char *)node2->name)
161 xml_dom_error(root, "expected <route>, got ");
163 std::cout << "processing /yp2/routes/route" << std::endl;
165 // process <filter> nodes in third level
166 const xmlNode* node3 = node2->children;
167 for (; node3 && node3->type != XML_ELEMENT_NODE; node3 = node3->next)
169 if (std::string((const char *)node3->name)
171 xml_dom_error(root, "expected <filter>, got ");
173 std::cout << "processing /yp2/routes/route/filter" << std::endl;
180 void parse_xml_config_xmlreader() {
182 xmlTextReader* reader;
183 //reader->SetParserProp(libxml2.PARSER_SUBST_ENTITIES,1);
185 //reader = xmlReaderForFile(m_xmlconf.c_str(), NULL, 0);
186 reader = xmlReaderWalker(m_xmlconf_doc);
188 if (reader == NULL) {
189 std::cerr << "failed to read XML config file "
191 << m_xmlconf << std::endl;
196 // root element processing
197 xml_progress_deep_to_element(reader);
198 if (std::string("yp2") != (const char*)xmlTextReaderConstName(reader))
199 xml_error(reader, "root element must be named <yp2>");
201 std::cout << "<" << xmlTextReaderConstName(reader);
203 //if (xmlTextReaderHasAttributes(reader))
204 //if ((!xmlTextReaderMoveToAttributeNs(reader, NULL,
205 // (const xmlChar*)"http://indexdata.dk/yp2/config/1" )))
206 if ((!xmlTextReaderMoveToFirstAttribute(reader))
207 || (! xmlTextReaderIsNamespaceDecl(reader))
208 || (std::string("http://indexdata.dk/yp2/config/1")
209 != (const char*)xmlTextReaderConstValue(reader)))
210 xml_error(reader, "expected root element <yp2> in namespace "
211 "'http://indexdata.dk/yp2/config/1'");
213 std::cout << " " << xmlTextReaderConstName(reader) << "=\""
214 << xmlTextReaderConstValue(reader) << "\">"
215 //<< xmlTextReaderIsNamespaceDecl(reader)
219 // start element processing
220 xml_progress_deep_to_element(reader);
221 if (std::string("start") != (const char*)xmlTextReaderConstName(reader)
222 || !xmlTextReaderMoveToFirstAttribute(reader)
223 || std::string("route") != (const char*)xmlTextReaderConstName(reader)
225 xml_error(reader, "start element <start route=\"route_id\"/> expected");
227 std::cout << "<start " << xmlTextReaderConstName(reader) << "=\""
228 << xmlTextReaderConstValue(reader) << "\"/>" << std::endl;
229 //<< xmlTextReaderGetAttribute(reader, (const xmlChar *)"route")
232 // filters element processing
233 xml_progress_flat_to_element(reader);
235 if (std::string("filters") != (const char*)xmlTextReaderConstName(reader)
237 xml_error(reader, "filters element <filters> expected");
239 std::cout << "<filters>" << std::endl;
242 // filter element processing
243 xml_progress_deep_to_element(reader);
244 if (std::string("filter") != (const char*)xmlTextReaderConstName(reader)
246 xml_error(reader, "filter element <filter id=\"some_id\" "
247 "type=\"some_type\"/> expected");
249 while (std::string("filter") == (const char*)xmlTextReaderConstName(reader)){
250 std::string filter_id;
251 std::string filter_type;
252 if (!xmlTextReaderMoveToFirstAttribute(reader)
253 || std::string("id") != (const char*)xmlTextReaderConstName(reader))
254 xml_error(reader, "filter element <filter id=\"some_id\" "
255 "type=\"some_type\"/> expected");
256 filter_id = (const char*)xmlTextReaderConstValue(reader);
257 if (!xmlTextReaderMoveToNextAttribute(reader)
258 || std::string("type") != (const char*)xmlTextReaderConstName(reader))
259 xml_error(reader, "filter element <filter id=\"some_id\" "
260 "type=\"some_type\"/> expected");
261 filter_type = (const char*)xmlTextReaderConstValue(reader);
262 std::cout << "<filter id=\"" << filter_id
263 << "\" type=\"" << filter_type << "\"/>"
265 xml_progress_flat_to_element(reader);
268 std::cout << "</filters>" << std::endl;
271 // routes element processing
272 // xml_progress_flat_to_element(reader);
273 if (std::string("routes") != (const char*)xmlTextReaderConstName(reader)
275 xml_error(reader, "routes element <routes> expected");
277 std::cout << "<routes>" << std::endl;
278 // route element processing
279 xml_progress_deep_to_element(reader);
280 if (std::string("route") != (const char*)xmlTextReaderConstName(reader)
282 xml_error(reader, "route element <route id=\"some_id\" "
283 "type=\"some_type\"/> expected");
284 while (std::string("route") == (const char*)xmlTextReaderConstName(reader)){
285 std::string route_id;
286 if (!xmlTextReaderMoveToFirstAttribute(reader)
287 || std::string("id") != (const char*)xmlTextReaderConstName(reader))
288 xml_error(reader, "route element <route id=\"some_id\"/> expected");
289 route_id = (const char*)xmlTextReaderConstValue(reader);
292 std::cout << "<route id=\"" << route_id << "\">" << std::endl;
293 std::cout << "</route>" << std::endl;
294 xml_progress_flat_to_element(reader);
297 std::cout << "</routes>" << std::endl;
299 std::cout << "</yp2>" << std::endl;
301 xml_debug_print(reader);
304 // freeing C xml reader libs
305 xmlFreeTextReader(reader);
307 std::cerr << "Parsing failed of XML configuration"
309 << m_xmlconf << std::endl;
314 void xml_error ( xmlTextReader* reader, std::string msg)
316 std::cerr << "ERROR: " << msg << " "
317 << xmlTextReaderGetParserLineNumber(reader) << ":"
318 << xmlTextReaderGetParserColumnNumber(reader) << " "
319 << xmlTextReaderConstName(reader) << " "
320 << xmlTextReaderDepth(reader) << " "
321 << xmlTextReaderNodeType(reader) << std::endl;
324 void xml_debug_print ( xmlTextReader* reader)
326 // processing all other elements
327 //while (xmlTextReaderMoveToElement(reader)) // reads next element ??
328 //while (xmlTextReaderNext(reader)) //does not descend, keeps level
329 while (xmlTextReaderRead(reader)) // descends into all subtree nodes
330 std::cout << xmlTextReaderGetParserLineNumber(reader) << ":"
331 << xmlTextReaderGetParserColumnNumber(reader) << " "
332 << xmlTextReaderDepth(reader) << " "
333 << xmlTextReaderNodeType(reader) << " "
334 << "ConstName " << xmlTextReaderConstName(reader) << " "
338 bool xml_progress_deep_to_element(xmlTextReader* reader)
341 while(xmlTextReaderRead(reader)
342 && xmlTextReaderNodeType(reader) != XML_ELEMENT_NODE
343 && !( xmlTextReaderNodeType(reader)
344 == XML_READER_TYPE_END_ELEMENT
345 && 0 == xmlTextReaderDepth(reader))
351 bool xml_progress_flat_to_element(xmlTextReader* reader)
355 while(xmlTextReaderNext(reader)
356 && xmlTextReaderNodeType(reader) != XML_ELEMENT_NODE
357 && !( xmlTextReaderNodeType(reader)
358 == XML_READER_TYPE_END_ELEMENT
359 && 0 == xmlTextReaderDepth(reader))
376 * indent-tabs-mode: nil
377 * c-file-style: "stroustrup"
379 * vim: shiftwidth=4 tabstop=8 expandtab