00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <xpath.h>
00014 #include <xpathresult.h>
00015 #include <to_xml.h>
00016 #include <iostream>
00017 #include <streambuf>
00018
00019 #ifndef XPATHITERATOR_H
00020 #define XPATHITERATOR_H
00021
00022 class abstract_xpath_iterator{
00023 protected:
00024 abstract_xpath_iterator * parent;
00025 public:
00026 class xpath_iterator_functor{
00027 public:
00028 std::ostream* out;
00029 xpath_iterator_functor() {
00030 out = &std::cout;
00031 }
00032 virtual void apply(abstract_xpath_iterator&) = 0;
00033 virtual ~xpath_iterator_functor(){
00034 }
00035 };
00036 abstract_xpath_iterator(abstract_xpath_iterator* par): parent(par) {
00037 }
00038 virtual void ApplyByPath(XPath::const_iterator, XPath::const_iterator, xpath_iterator_functor& f) = 0;
00039 virtual void ApplyByXPath(const XPath& xp, xpath_iterator_functor& f) {
00040 ApplyByPath(xp.begin(), xp.end(), f);
00041 return;
00042 }
00043 virtual void getValueByPath(XPath::const_iterator, XPath::const_iterator, XPathResult&) = 0;
00044 virtual XPathResult getValueByXPath(const XPath& xp) {
00045 XPathResult res;
00046 getValueByPath(xp.begin(), xp.end(), res);
00047 return res;
00048 }
00049 virtual ~abstract_xpath_iterator() {
00050 }
00051 virtual bool checkPathCondition(XPath::const_iterator, XPath::const_iterator) = 0;
00052 virtual bool checkXPathCondition(XPath xp) {
00053 return checkPathCondition(xp.begin(), xp.end());
00054 }
00055 virtual void to_xml(std::ostream& = std::cout) = 0;
00056 };
00057
00058 template<typename T>
00059 class xpath_iterator;
00060
00061 template<typename T>
00062 class pointer_collector: public abstract_xpath_iterator::xpath_iterator_functor{
00063 public:
00064 XPathResult rs;
00065 virtual void apply(abstract_xpath_iterator& it) {
00066 rs.push_back(((xpath_iterator<T>*)&it)->value);
00067 }
00068 };
00069
00070 #define FUNCTOR_DECLARE(name) \
00071 class name: public abstract_xpath_iterator::xpath_iterator_functor { \
00072 public: \
00073 virtual void apply(abstract_xpath_iterator& i); \
00074 };
00075
00076 #define FUNCTOR_BEGIN(name) \
00077 void name::apply(abstract_xpath_iterator& i) {
00078
00079 #define FUNCTOR_END() \
00080 }
00081
00082 FUNCTOR_DECLARE(printer)
00083
00084 template<typename T>
00085 class xpath_iterator: public abstract_xpath_iterator {
00086 public:
00087 T* value;
00088 xpath_iterator(abstract_xpath_iterator* par, T* val): abstract_xpath_iterator(par), value(val) {
00089 }
00090 virtual void ApplyByPath(XPath::const_iterator xp, XPath::const_iterator xe, xpath_iterator_functor& f){
00091 if(xp == xe) {
00092 f.apply(*this);
00093 return;
00094 }
00095 }
00096 virtual void getValueByPath(XPath::const_iterator xp, XPath::const_iterator xe, XPathResult& res) {
00097 if(xp == xe && value != NULL) {
00098 res.push_back((void*)value);
00099 return;
00100 }
00101 if(xp->type == XP_ELEMENT && xp->text == ".."){
00102 parent->getValueByPath(++xp, xe, res);
00103 return;
00104 }
00105 }
00106 void setValue(T* val) {
00107 value = val;
00108 }
00109 virtual bool checkPathCondition(XPath::const_iterator, XPath::const_iterator) {
00110 return true;
00111 }
00112 virtual void to_xml(std::ostream& out = std::cout) {
00113 if(value)
00114 ::to_xml(*value, NULL, out);
00115 }
00116 };
00117
00118 #endif //XPATHITERATOR_H