UtilsXML.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25  */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30  */
31 /*
32  * UtilsXML.h
33  *
34  * Created on: Jun 24, 2012
35  * Author: mpeura
36  */
37 
38 
39 
40 #ifndef DRAIN_UTILS_XML
41 #define DRAIN_UTILS_XML
42 
43 #include <ostream>
44 
45 #include <drain/Sprinter.h>
46 // #include <drain/FlexibleVariable.h>
47 
48 // #include "ClassXML.h"
49 
50 namespace drain {
51 
52 
53 class UtilsXML {
54 
55 public:
56 
58  typedef drain::Path<std::string,'/'> path_t; // consider xml_path_t
59  typedef path_t::elem_t path_elem_t;
60 
61  typedef std::list<path_t> path_list_t;
62 
64 
75  // This could also be in TreeXMLutilities
76  template <class V>
77  static
78  bool findById(const V & tree, const std::string & tag, typename V::path_t & result, const typename V::path_t & path = path_t());
79 
81 
91  // This could also be in TreeXMLutilities
92  template <class T>
93  static
94  bool findById(const T & tree, const std::string & tag, path_list_t & result, const path_t & path = path_t());
95 
98  template <class T, class E>
99  static
100  bool findByTag(const T & tree, const E & tag, path_list_t & result, const path_t & path = path_t());
101 
103  // This could also be in TreeXMLutilities
108  template <class T, class E>
109  static
110  bool findByTags(const T & tree, const std::set<E> & tags, path_list_t & result, const path_t & path = path_t());
111 
113 
119  template <class T, class C>
120  static
121  bool findByClass(const T & t, const C & cls, std::list<typename T::path_elem_t> & result);
122 
124 
129  //template <class V, class E>
130  template <class T, class C>
131  static inline
132  bool findByClass(const T & t, const C & cls, path_list_t & result, const path_t & path = path_t());
133 
134 
135 
136 
137 };
138 
139 
140 template <class T>
141 bool UtilsXML::findById(const T & t, const std::string & id, typename T::path_t & result, const typename T::path_t & path){
142 
143  if (t->id == id){
144  result = path;
145  return true;
146  }
147 
148  // Recursion
149  for (const auto & entry: t){
150  if (findById(entry.second, id, result, path_t(path, entry.first))){
151  return true;
152  }
153  }
154 
155  return false;
156  //return !result.empty();
157 }
158 
159 
160 
161 template <class T>
162 bool UtilsXML::findById(const T & t, const std::string & id, UtilsXML::path_list_t & result, const path_t & path){
163 
164  if (t->id == id){
165  result.push_back(path);
166  }
167 
168  for (const auto & entry: t){
169  findById(entry.second, id, result, path_t(path, entry.first));
170  }
171 
172  return !result.empty();
173 }
174 
178 //template <class N>
179 template <class T, class N>
180 bool UtilsXML::findByTag(const T & t, const N & tag, UtilsXML::path_list_t & result, const path_t & path){
181 
182  // const T & t = tree(path);
183 
184  if (t->typeIs(tag)){
185  result.push_back(path);
186  }
187 
188  for (const auto & entry: t){
189  findByTag(entry.second, tag, result, path_t(path, entry.first));
190  }
191 
192  return !result.empty();
193 
194 }
195 
199 template <class T,class N>
200 bool UtilsXML::findByTags(const T & t, const std::set<N> & tags, UtilsXML::path_list_t & result, const UtilsXML::path_t & path){
201 
202  // const T & t = tree(path);
203 
204  //if (t->typeIs(tag)){
205  if (tags.count(t->getType()) > 0){
206  result.push_back(path);
207  }
208 
209  for (const auto & entry: t){
210  findByTags(entry.second, tags, result, path_t(path, entry.first));
211  }
212 
213  //return result;
214  return !result.empty();
215 }
216 
217 
218 
219 template <class T, class C>
220 bool UtilsXML::findByClass(const T & t, const C & cls, UtilsXML::path_list_t & result, const UtilsXML::path_t & path){
221 
222  // drain::Logger mout(__FILE__,__FUNCTION__);
223 
224  if (t->classList.has(cls)){
225  result.push_back(path);
226  }
227 
228  for (const auto & entry: t){
229  // mout.warn(t->get("name", "<name>"), "... continuing to: ", path_t(path, entry.first));
230  findByClass(entry.second, cls, result, path_t(path, entry.first));
231  }
232 
233  return !result.empty();
234 }
235 
237 template <class T, class C>
238 bool UtilsXML::findByClass(const T & t, const C & cls, std::list<typename T::path_elem_t> & result){
239 
240  for (const auto & entry: t){
241  if (entry.second->hasClass(cls)){
242  result.push_back(entry.first);
243  }
244  }
245 
246  return !result.empty();
247 }
248 
249 
250 } // drain::
251 
252 #endif /* DRAIN_UTILS_XML */
253 
Definition: Path.h:112
Definition: UtilsXML.h:53
static bool findByTag(const T &tree, const E &tag, path_list_t &result, const path_t &path=path_t())
static bool findByClass(const T &t, const C &cls, std::list< typename T::path_elem_t > &result)
Finds child elements in an XML structure by class name.
Definition: UtilsXML.h:238
static bool findByTags(const T &tree, const std::set< E > &tags, path_list_t &result, const path_t &path=path_t())
"Forward definition"
static bool findById(const V &tree, const std::string &tag, typename V::path_t &result, const typename V::path_t &path=path_t())
Find the first occurrence of given id using recursive breath-first search.
drain::Path< std::string,'/'> path_t
Tree path type. // TODO: extract from template.
Definition: UtilsXML.h:58
Definition: DataSelector.cpp:1277