Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members  

XPathOps.h

00001 #include <iostream>
00002 
00003 namespace judo
00004 {
00005     namespace XPath
00006     {
00007         class PositionOp : public Op
00008         {
00009         public:
00010             PositionOp(int pos) : Op(OP_POSITION, ""), _pos(pos)
00011             { }
00012 
00013             bool isValid(XPath::Value* ctxt)
00014             {
00015                 Value::ElemList elems = ctxt->getList();
00016 
00017                 Value::ElemList::iterator it = elems.begin();
00018                 for (int x = 1; (x < _pos) && (it != elems.end()); x++) it++;
00019                 if (it == elems.end())
00020                     return false;
00021                 //std::cout << "Got position " << (*it)->getName() << std::endl;
00022                 ctxt->setElems(*it);
00023 
00024                 return true;
00025             }
00026         private:
00027             int _pos;
00028         };
00029 
00030         class ContextOp : public Op
00031         {
00032         public:
00033             ContextOp(Op* op) : Op(OP_CONTEXT_CONDITION, ""), _op(op)
00034             { }
00035 
00036             ~ContextOp()
00037             {
00038                 delete _op;
00039             }
00040             
00041             bool isValid(XPath::Value* ctxt)
00042             {
00043                 Value::ElemList& elems = ctxt->getList();
00044                 Value::ElemList::iterator it = elems.begin();
00045                 while (it != elems.end())
00046                 {
00047                     Value::ElemList::iterator next = it;
00048                     ++next;
00049 
00050                     Value* tmp_ctxt = new Value(*it);
00051                     tmp_ctxt->in_context(true);
00052 
00053                     if (!_op->isValid(tmp_ctxt))
00054                     {
00055                         elems.erase(it);
00056                     }
00057 
00058                     it = next;
00059                 }
00060 
00061                 if (elems.empty())
00062                     return false;
00063 
00064                 return true;
00065             }
00066 
00067         private:
00068             Op* _op;
00069         };
00070         
00071         class NodeOp : public Op
00072         {
00073         public:
00074             NodeOp(const std::string& name, bool is_root=false) : 
00075                 Op(Op::OP_NODE, name), _is_root(is_root)
00076             { }
00077 
00078             std::string calcStr(judo::Element* elem)
00079             {
00080                 return elem->getCDATA();
00081             }
00082 
00083             bool isValid(XPath::Value* ctxt)
00084             {
00085                 judo::Element* elem = NULL;
00086 
00087                 // If we're only checking the root node bail early
00088                 if (_is_root)
00089                 {
00090                     elem = ctxt->getElem();
00091                     if (elem->getName() != _value)
00092                         return false;
00093                     return true;
00094                 }
00095 
00096                 // Get children
00097                 Value::ElemList& elems = ctxt->getList();
00098                 Value::ElemList valid_elems;
00099 
00100                 if (elems.empty())
00101                 {
00102                     elem = ctxt->getElem();
00103                     if (!elem)
00104                         return false;
00105                     elems.push_back(elem);
00106                 }
00107 
00108                 for (Value::ElemList::iterator it = elems.begin(); 
00109                         it != elems.end(); it++)
00110                 {
00111                     bool valid = false;
00112 
00113                     elem = *it;
00114 
00115                     judo::Element::iterator sit = elem->begin();
00116                     for (; sit != elem->end(); sit++)
00117                     {
00118                         if ((*sit)->getType() == Node::ntElement && 
00119                             (_value == "*") || ((*sit)->getName() == _value))
00120                         {
00121                             if (ctxt->in_context())
00122                                 valid = true;
00123                             else
00124                                 valid_elems.push_back(static_cast<judo::Element*>(*sit));
00125                         }
00126                     }
00127                     if (valid)
00128                         valid_elems.push_back(static_cast<judo::Element*>(*it));
00129                 }
00130 
00131                 // Nothing in the set
00132                 if (valid_elems.empty())
00133                     return false;
00134 
00135                 ctxt->setElems(valid_elems);
00136 
00137                 return true;
00138             }
00139         private:
00140             bool _is_root;
00141         };
00142 
00143         class AllOp : public Op
00144         {
00145         public:
00146             AllOp(const std::string& name) : Op(Op::OP_ALL, name)
00147             { }
00148 
00149             bool isValid(XPath::Value* ctxt)
00150             {
00151                 judo::Element* elem = NULL;
00152                 
00153                 // If we're only checking the root node bail early
00154                 if (_is_root)
00155                 {
00156                     elem = ctxt->getElem();
00157                     if (elem->getName() != _value)
00158                         return false;
00159                     return true;
00160                 }
00161 
00162                 // Get children
00163                 Value::ElemList& elems = ctxt->getList();
00164                 Value::ElemList valid_elems;
00165 
00166                 if (elems.empty())
00167                 {
00168                     return false;
00169                 }
00170 
00171                 for (Value::ElemList::iterator it = elems.begin(); 
00172                         it != elems.end(); it++)
00173                 {
00174                     descend(static_cast<judo::Element*>(*it),&valid_elems);
00175                 }
00176 
00177                 // Nothing in the set
00178                 if (valid_elems.empty())
00179                     return false;
00180 
00181                 ctxt->setElems(valid_elems);
00182 
00183                 return true;
00184             }
00185 
00186             void descend(judo::Element* elem, Value::ElemList* valid_elems)
00187             {
00188                 judo::Element* temp_elem = NULL;
00189                 
00190                 if ((_value == "*") || (elem->getName() == _value))
00191                 {
00192                     valid_elems->push_back(elem);
00193                 }
00194 
00195                 judo::Element::iterator it = elem->begin();
00196                 for (; it != elem->end(); it++)
00197                 {
00198                     if ((*it)->getType() == Node::ntElement)
00199                     {
00200                         temp_elem = static_cast<judo::Element*>(*it);
00201 
00202                         descend(temp_elem,valid_elems);
00203                     }
00204                 }
00205             }
00206             
00207         private:
00208             bool _is_root;
00209         };
00210 
00211         class EqualOp : public Op
00212         {
00213         public:
00214             EqualOp(Op* op_lh, Op* op_rh) : 
00215                 Op(Op::OP_EQUAL, ""), _op_lh(op_lh), _op_rh(op_rh)
00216             { }
00217 
00218             ~EqualOp()
00219             {
00220                 delete _op_lh;
00221                 delete _op_rh;
00222             }
00223 
00224             bool isValid(XPath::Value* ctxt)
00225             {
00226                 XPath::Value* tmp_ctxt = new Value(ctxt->getList());
00227 
00228                 if (!_op_lh->isValid(tmp_ctxt) || !_op_rh->isValid(tmp_ctxt))
00229                     return false;
00230 
00231                 Value::ElemList& elems = tmp_ctxt->getList();
00232                 Value::ElemList::iterator it = elems.begin();
00233 
00234                 while (it != elems.end())
00235                 {
00236                     Value::ElemList::iterator next = it;
00237                     ++next;
00238 
00239                     judo::Element* elem = *it;
00240                     if (_op_lh->calcStr(elem) != _op_rh->calcStr(elem))
00241                     {
00242                         elems.erase(it);
00243                     }
00244                     it = next;
00245                 }
00246 
00247                 if (elems.empty())
00248                 {
00249                     Value::ElemList& elems = ctxt->getList();
00250                     elems.clear();
00251                     return false;
00252                 }
00253 
00254                 return true;
00255             }
00256 
00257         private:
00258             Op* _op_lh;
00259             Op* _op_rh;
00260         };
00261 
00262         class NotEqualOp : public Op
00263         {
00264         public:
00265             NotEqualOp(Op* op_lh, Op* op_rh) : 
00266                 Op(Op::OP_NOTEQUAL, ""), _op_lh(op_lh), _op_rh(op_rh)
00267             { }
00268 
00269             ~NotEqualOp()
00270             {
00271                 delete _op_lh;
00272                 delete _op_rh;
00273             }
00274 
00275             bool isValid(XPath::Value* ctxt)
00276             {
00277                 XPath::Value* tmp_ctxt = new Value(ctxt->getList());
00278 
00279                 if (!_op_lh->isValid(tmp_ctxt) || !_op_rh->isValid(tmp_ctxt))
00280                     return false;
00281 
00282                 Value::ElemList& elems = tmp_ctxt->getList();
00283                 Value::ElemList::iterator it = elems.begin();
00284 
00285                 while (it != elems.end())
00286                 {
00287                     Value::ElemList::iterator next = it;
00288                     ++next;
00289 
00290                     judo::Element* elem = *it;
00291                     if (_op_lh->calcStr(elem) == _op_rh->calcStr(elem))
00292                     {
00293                         elems.erase(it);
00294                     }
00295                     it = next;
00296                 }
00297 
00298                 if (elems.empty())
00299                 {
00300                     Value::ElemList& elems = ctxt->getList();
00301                     elems.clear();
00302                     return false;
00303                 }
00304 
00305                 return true;
00306             }
00307 
00308         private:
00309             Op* _op_lh;
00310             Op* _op_rh;
00311         };
00312 
00313         class AttributeOp : public Op
00314         {
00315         public:
00316             AttributeOp(const std::string& name) : Op(Op::OP_ATTRIBUTE, name)
00317             { }
00318 
00319             std::string getValue()
00320             {
00321                 return _val;
00322             }
00323 
00324             std::string calcStr(judo::Element* elem)
00325             {
00326                 return elem->getAttrib(_value);
00327             }
00328             
00329             bool isValid(XPath::Value* ctxt)
00330             {
00331                 Value::ElemList& elems = ctxt->getList();
00332                 Value::ElemList::iterator it = elems.begin();
00333 
00334                 Value::ValueList values;
00335                 Value::AttribMap attribs;
00336 
00337                 while (it != elems.end())
00338                 {
00339                     Value::ElemList::iterator next = it;
00340                     ++next;
00341 
00342                     judo::Element* elem = *it;
00343                     if (_value != "*")
00344                     {
00345                         _val = calcStr(elem);
00346                         if (_val.empty())
00347                             elems.erase(it);
00348                         else
00349                             values.push_back(_val);
00350                     }
00351                     else
00352                     {
00353                         Value::AttribMap temp_attribs = elem->getAttribs();
00354                         if (temp_attribs.empty())
00355                         {
00356                             elems.erase(it);
00357                         }
00358                         else
00359                         {
00360                             Value::AttribMap::const_iterator ait = temp_attribs.begin();
00361                             while(ait != temp_attribs.end())
00362                             {
00363                                 attribs[ait->first] = ait->second;
00364                                 ait++;
00365                             }
00366                         }
00367                     }
00368 
00369                     it = next;
00370                 }
00371 
00372                 if (elems.empty())
00373                 {
00374                     //std::cout << "Invalid attribute: " << _value << std::endl;
00375                     return false;
00376                 }
00377 
00378                 ctxt->setValues(values);
00379                 ctxt->setAttribs(attribs);
00380 
00381                 return true;
00382             }
00383         private:
00384             std::string _val;
00385         };
00386 
00387         class AndOp : public Op
00388         {
00389         public:
00390             AndOp(Op* lh, Op* rh) : Op(OP_AND, "and"), _lh(lh), _rh(rh)
00391             { }
00392 
00393             ~AndOp()
00394             {
00395                 delete _lh;
00396                 delete _rh;
00397             }
00398 
00399             bool isValid(XPath::Value* ctxt)
00400             {
00401                 if (_lh->isValid(ctxt) && _rh->isValid(ctxt))
00402                     return true;
00403                 else
00404                     return false;
00405             }
00406         private:
00407             Op* _lh;
00408             Op* _rh;
00409         };
00410 
00411         class OrOp : public Op
00412         {
00413         public:
00414             OrOp(Op* lh, Op* rh) : Op(OP_OR, "or"), _lh(lh), _rh(rh)
00415             { }
00416 
00417             ~OrOp()
00418             {
00419                 delete _lh;
00420                 delete _rh;
00421             }
00422 
00423             bool isValid(XPath::Value* ctxt)
00424             {
00425                 Value::ElemList& elems = ctxt->getList();
00426                 Value::ElemList::iterator it = elems.begin();
00427                 while (it != elems.end())
00428                 {
00429                     Value::ElemList::iterator next = it;
00430                     ++next;
00431 
00432                     Value* tmp_ctxt_l = new Value(*it);
00433                     tmp_ctxt_l->in_context(true);
00434                     Value* tmp_ctxt_r = new Value(*it);
00435                     tmp_ctxt_r->in_context(true);
00436                     if (!_lh->isValid(tmp_ctxt_l) && !_rh->isValid(tmp_ctxt_r))
00437                     {
00438                         elems.erase(it);
00439                     }
00440 
00441                     it = next;
00442                 }
00443 
00444                 if (elems.empty())
00445                     return false;
00446 
00447                 return true;
00448             }
00449         private:
00450             Op* _lh;
00451             Op* _rh;
00452         };
00453 
00454         class FunctionOp : public Op
00455         {
00456         public:
00457             FunctionOp(const std::string& func) : Op(OP_FUNCTION, func) , _closed(false)
00458             { }
00459 
00460             ~FunctionOp()
00461             {
00462                 while (!_arg_list.empty())
00463                 {
00464                     Op *op = _arg_list.back();
00465                     _arg_list.pop_back();
00466                     delete op;
00467                 }
00468             }
00469 
00470             bool isValid(XPath::Value* ctxt)
00471             {
00472                 if (_value == "text")
00473                     return function_text(ctxt);
00474 
00475                 if (_value == "name")
00476                     return function_name(ctxt);
00477 
00478                 if (_value == "not")
00479                     return function_not(ctxt);
00480 
00481                 if (_value == "starts-with")
00482                     return function_startswith(ctxt);
00483 
00484                 std::cerr << "Unknown query function " << _value << "()" << std::endl;
00485                 return false;
00486             }
00487 
00488             std::string calcStr(judo::Element* elem)
00489             {
00490                 if (_value == "text")
00491                     return value_text(elem);
00492 
00493                 if (_value == "name")
00494                     return value_name(elem);
00495 
00496                 std::cerr << "Unknown internal value function funtion_" << _value << "_value()" << std::endl;
00497                 return "";
00498             }
00499             
00500             void addArg(Op* arg)
00501             {
00502                 _arg_list.push_back(arg);
00503             }
00504 
00505             bool function_text(XPath::Value* ctxt)
00506             {
00507                 Value::ElemList& elems = ctxt->getList();
00508                 Value::ElemList::iterator it = elems.begin();
00509 
00510                 Value::ValueList values;
00511 
00512                 while (it != elems.end())
00513                 {
00514                     std::string value;
00515                     Value::ElemList::iterator next = it;
00516                     ++next;
00517 
00518                     judo::Element* elem = *it;
00519                     value = value_text(elem);
00520                     values.push_back(value);
00521 
00522                     it = next;
00523                 }
00524 
00525                 if (elems.empty())
00526                 {
00527                     return false;
00528                 }
00529 
00530                 ctxt->setValues(values);
00531 
00532                 return true;
00533             }
00534             
00535             std::string value_text(judo::Element* elem)
00536             {
00537                 return elem->getCDATA();
00538             }
00539             
00540             bool function_name(XPath::Value* ctxt)
00541             {
00542                 Value::ElemList& elems = ctxt->getList();
00543                 Value::ElemList::iterator it = elems.begin();
00544 
00545                 Value::ValueList values;
00546 
00547                 while (it != elems.end())
00548                 {
00549                     std::string value;
00550                     Value::ElemList::iterator next = it;
00551                     ++next;
00552 
00553                     judo::Element* elem = *it;
00554                     value = value_name(elem);
00555                     values.push_back(value);
00556 
00557                     it = next;
00558                 }
00559 
00560                 if (elems.empty())
00561                 {
00562                     return false;
00563                 }
00564 
00565                 ctxt->setValues(values);
00566 
00567                 return true;
00568             }
00569             
00570             std::string value_name(judo::Element* elem)
00571             {
00572                 return elem->getName();
00573             }
00574 
00575             bool function_not(XPath::Value* ctxt)
00576             {
00577                 Value::ElemList& elems = ctxt->getList();
00578                 Value::ElemList::iterator it = elems.begin();
00579 
00580                 while (it != elems.end())
00581                 {
00582                     std::string value;
00583                     Value::ElemList::iterator next = it;
00584                     ++next;
00585 
00586                     Value* tmp_ctxt = new Value(*it);
00587                     tmp_ctxt->in_context(true);
00588 
00589                     if (_arg_list[0]->isValid(tmp_ctxt))
00590                     {
00591                         elems.erase(it);
00592                     }
00593 
00594                     it = next;
00595                 }
00596 
00597                 if (elems.empty())
00598                 {
00599                     return false;
00600                 }
00601 
00602                 return true;
00603             }
00604         
00605             bool function_startswith(XPath::Value* ctxt)
00606             {
00607                 Value::ElemList& elems = ctxt->getList();
00608                 Value::ElemList::iterator it = elems.begin();
00609 
00610                 Query::OpList::iterator arg_it = _arg_list.begin();
00611 
00612                 while (it != elems.end())
00613                 {
00614                     std::string value;
00615                     Value::ElemList::iterator next = it;
00616                     ++next;
00617 
00618                     judo::Element* elem = *it;
00619                     std::string val1 = _arg_list[0]->calcStr(elem);
00620                     std::string val2 = _arg_list[1]->calcStr(elem);
00621 
00622                     if (val1.find(val2,0) != 0)
00623                     {
00624                         elems.erase(it);
00625                     }
00626 
00627                     it = next;
00628                 }
00629 
00630                 if (elems.empty())
00631                 {
00632                     return false;
00633                 }
00634 
00635                 return true;
00636             }
00637 
00638         private:
00639             Query::OpList _arg_list;
00640             bool _closed;
00641         };
00642 
00643     };
00644 };

Generated on Thu Jul 24 13:31:51 2003 for jabberoo by doxygen1.3-rc3