CrystalSpace

Public API Reference

csutil/documenthelper.h

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 2005 by Marten Svanfeldt
00003 
00004   This library is free software; you can redistribute it and/or
00005   modify it under the terms of the GNU Library General Public
00006   License as published by the Free Software Foundation; either
00007   version 2 of the License, or (at your option) any later version.
00008 
00009   This library is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012   Library General Public License for more details.
00013 
00014   You should have received a copy of the GNU Library General Public
00015   License along with this library; if not, write to the Free
00016   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 */
00018 
00019 #ifndef __CSUTIL_DOCUMENTHELPER_H__
00020 #define __CSUTIL_DOCUMENTHELPER_H__
00021 
00027 #include "csutil/csstring.h"
00028 #include "csutil/refarr.h"
00029 #include "csutil/regexp.h"
00030 #include "csutil/scf_implementation.h"
00031 #include "csutil/util.h"
00032 
00033 #include "iutil/document.h"
00034 
00035 namespace CS
00036 {
00041   namespace DocumentHelper
00042   {
00043     namespace Implementation
00044     {
00049       template<class T>
00050       class FilterDocumentNodeIterator : public 
00051         scfImplementation1 <FilterDocumentNodeIterator<T>, 
00052           iDocumentNodeIterator>
00053       {
00054       public:
00055         FilterDocumentNodeIterator (csRef<iDocumentNodeIterator> parent,
00056           T filter) : scfImplementation1<FilterDocumentNodeIterator<T>, 
00057             iDocumentNodeIterator> (this), parent (parent), filter (filter)
00058         {
00059           ForwardIterator ();
00060         }
00061 
00062         // -- iDocumentNodeIterator
00064         virtual bool HasNext ()
00065         {
00066           return nextElement.IsValid ();
00067         }
00068 
00070         virtual csRef<iDocumentNode> Next ()
00071         {
00072           csRef<iDocumentNode> current = nextElement;
00073           ForwardIterator ();
00074           return current;
00075         }
00076 
00077       private:
00078         void ForwardIterator ()
00079         {
00080           if (!parent) nextElement = 0;
00081 
00082           while (parent->HasNext ())
00083           {
00084             csRef<iDocumentNode> parentNext = parent->Next ();
00085             if (filter (parentNext))
00086             {
00087               nextElement = parentNext;
00088               return;
00089             }
00090           }
00091           nextElement = 0;
00092           parent = 0;
00093         }
00094 
00095         csRef<iDocumentNodeIterator> parent;
00096         T filter;
00097         csRef<iDocumentNode> nextElement;
00098       };
00099     }
00100     
00107     template<class T>
00108     void RemoveDuplicateChildren (iDocumentNode *rootNode, T eq)
00109     {
00110       csRef<iDocumentNodeIterator> it = rootNode->GetNodes ();
00111       RemoveDuplicateChildren (rootNode, it, eq);
00112     }
00113 
00120     template<class T>
00121     void RemoveDuplicateChildren (iDocumentNode *rootNode,
00122       csRef<iDocumentNodeIterator> childIt, T eq)
00123     {
00124       typedef csRefArray<iDocumentNode> NodeListType;
00125       NodeListType nodesToRemove;
00126       NodeListType nodesToKeep;
00127 
00128       if (!childIt) return;
00129 
00130       while (childIt->HasNext ())
00131       {
00132         csRef<iDocumentNode> node = childIt->Next ();
00133         //compare it to those we already have
00134         bool keep = true;
00135 
00136         NodeListType::Iterator it = nodesToKeep.GetIterator ();
00137         while (it.HasNext ())
00138         {
00139           csRef<iDocumentNode> keepNode = it.Next ();
00140           if (keepNode->Equals (node))
00141           {
00142             keep = false; 
00143             break;
00144           }
00145           if (eq (node, keepNode))
00146           {
00147             keep = false;
00148             break;
00149           }
00150         }
00151 
00152         if (keep)
00153         {
00154           nodesToKeep.Push (node);
00155         }
00156         else
00157         {
00158           nodesToRemove.Push (node);
00159         }
00160       }
00161 
00162       while (nodesToRemove.GetSize ())
00163       {
00164         csRef<iDocumentNode> node = nodesToRemove.Pop ();
00165         rootNode->RemoveNode (node);
00166       }
00167     }
00168 
00175     struct NodeNameCompare
00176     {
00177       bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
00178       {
00179         if (node1->GetType () != CS_NODE_ELEMENT) return false;
00180         if (node2->GetType () != CS_NODE_ELEMENT) return false;
00181 
00182         const char* name1 = node1->GetValue ();
00183         const char* name2 = node2->GetValue ();
00184         if (!csStrCaseCmp (name1, name2)) return true;
00185         return false;
00186       }
00187     };
00188 
00193     struct NodeAttributeCompare
00194     {
00195       NodeAttributeCompare (const char* attributeName)
00196         : attributeName (attributeName)
00197       {
00198       }
00199 
00200       bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
00201       {
00202         if (node1->GetType () != CS_NODE_ELEMENT) return false;
00203         if (node2->GetType () != CS_NODE_ELEMENT) return false;
00204 
00205         csRef<iDocumentAttribute> attribute1 = 
00206           node1->GetAttribute (attributeName.GetData ());
00207         csRef<iDocumentAttribute> attribute2 = 
00208           node2->GetAttribute (attributeName.GetData ());
00209         if (!attribute1 || !attribute2) return false;
00210 
00211         if (!csStrCaseCmp (attribute1->GetValue (), attribute2->GetValue ())) 
00212           return true;
00213 
00214         return false;
00215       }
00216     private:
00217       csString attributeName;
00218     };
00219 
00223     struct NodeValueTest
00224     {
00225       NodeValueTest (const char* value)
00226         : value (value)
00227       {}
00228 
00229       bool operator () (iDocumentNode *node)
00230       {
00231         if (!node) return false;
00232 
00233         const char *nodeValue = node->GetValue ();
00234         return (value == nodeValue);
00235       }
00236 
00237     private:
00238       csString value;
00239     };
00240 
00244     struct NodeAttributeValueTest
00245     {
00246       NodeAttributeValueTest (const char *attribute, const char* value)
00247         : attribute (attribute), value (value)
00248       {}
00249 
00250       bool operator () (iDocumentNode *node)
00251       {
00252         if (!node) return false;
00253 
00254         const char* attributeValue = node->GetAttributeValue (
00255                 attribute.GetData ());
00256 
00257         return (value == attributeValue);
00258       }
00259 
00260     private:
00261       csString attribute;
00262       csString value;
00263     };
00264 
00269     struct NodeAttributeRegexpTest
00270     {
00271       NodeAttributeRegexpTest (const char *attribute, const char* regexp)
00272         : attribute (attribute), valueMatcher (regexp)
00273       {
00274       }
00275 
00276       bool operator () (iDocumentNode *node)
00277       {
00278         if (!node) return false;
00279 
00280         const char* attributeValue = node->GetAttributeValue (
00281                 attribute.GetData ());
00282 
00283         return (valueMatcher.Match (attributeValue, csrxIgnoreCase)
00284                 == csrxNoError);
00285       }
00286 
00287     private:
00288       csString attribute;
00289       csRegExpMatcher valueMatcher;
00290     };
00304     template<class T>
00305     csPtr<iDocumentNodeIterator> FilterDocumentNodeIterator(
00306       csRef<iDocumentNodeIterator> parent, T filter)
00307     {
00308       return new Implementation::FilterDocumentNodeIterator<T>
00309         (parent, filter);
00310     }
00311   }
00312 } //namespace CS
00313 
00314 #endif

Generated for Crystal Space by doxygen 1.4.7