CrystalSpace

Public API Reference

Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

documenthelper.h

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 
00022 #include "csutil/refarr.h"
00023 #include "csutil/regexp.h"
00024 #include "csutil/scf_implementation.h"
00025 
00026 #include "iutil/document.h"
00027 
00028 namespace CrystalSpace
00029 {
00031   namespace DocumentHelper
00032   {
00033     namespace Implementation
00034     {
00039       template<class T>
00040       class FilterDocumentNodeIterator : public 
00041         scfImplementation1 <FilterDocumentNodeIterator<T>, 
00042           iDocumentNodeIterator>
00043       {
00044       public:
00045         FilterDocumentNodeIterator (csRef<iDocumentNodeIterator> parent,
00046           T filter) : scfImplementation1<FilterDocumentNodeIterator<T>, 
00047             iDocumentNodeIterator> (this), parent (parent), filter (filter)
00048         {
00049           ForwardIterator ();
00050         }
00051 
00052         // -- iDocumentNodeIterator
00054         virtual bool HasNext ()
00055         {
00056           return nextElement.IsValid ();
00057         }
00058 
00060         virtual csRef<iDocumentNode> Next ()
00061         {
00062           csRef<iDocumentNode> current = nextElement;
00063           ForwardIterator ();
00064           return current;
00065         }
00066 
00067       private:
00068         void ForwardIterator ()
00069         {
00070           if (!parent) nextElement = 0;
00071 
00072           while (parent->HasNext ())
00073           {
00074             csRef<iDocumentNode> parentNext = parent->Next ();
00075             if (filter (parentNext))
00076             {
00077               nextElement = parentNext;
00078               return;
00079             }
00080           }
00081           nextElement = 0;
00082           parent = 0;
00083         }
00084 
00085         csRef<iDocumentNodeIterator> parent;
00086         T filter;
00087         csRef<iDocumentNode> nextElement;
00088       };
00089     }
00090     
00097     template<class T>
00098     void RemoveDuplicateChildren (iDocumentNode *rootNode, T eq)
00099     {
00100       csRef<iDocumentNodeIterator> it = rootNode->GetNodes ();
00101       RemoveDuplicateChildren (rootNode, it, eq);
00102     }
00103 
00110     template<class T>
00111     void RemoveDuplicateChildren (iDocumentNode *rootNode,
00112       csRef<iDocumentNodeIterator> childIt, T eq)
00113     {
00114       typedef csRefArray<iDocumentNode> NodeListType;
00115       NodeListType nodesToRemove;
00116       NodeListType nodesToKeep;
00117 
00118       if (!childIt) return;
00119 
00120       while (childIt->HasNext ())
00121       {
00122         csRef<iDocumentNode> node = childIt->Next ();
00123         //compare it to those we already have
00124         bool keep = true;
00125 
00126         NodeListType::Iterator it = nodesToKeep.GetIterator ();
00127         while (it.HasNext ())
00128         {
00129           csRef<iDocumentNode> keepNode = it.Next ();
00130           if (keepNode->Equals (node))
00131           {
00132             keep = false; 
00133             break;
00134           }
00135           if (eq (node, keepNode))
00136           {
00137             keep = false;
00138             break;
00139           }
00140         }
00141 
00142         if (keep)
00143         {
00144           nodesToKeep.Push (node);
00145         }
00146         else
00147         {
00148           nodesToRemove.Push (node);
00149         }
00150       }
00151 
00152       while (nodesToRemove.GetSize ())
00153       {
00154         csRef<iDocumentNode> node = nodesToRemove.Pop ();
00155         rootNode->RemoveNode (node);
00156       }
00157     }
00158 
00165     struct NodeNameCompare
00166     {
00167       bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
00168       {
00169         if (node1->GetType () != CS_NODE_ELEMENT) return false;
00170         if (node2->GetType () != CS_NODE_ELEMENT) return false;
00171 
00172         const char* name1 = node1->GetValue ();
00173         const char* name2 = node2->GetValue ();
00174         if (!csStrCaseCmp (name1, name2)) return true;
00175         return false;
00176       }
00177     };
00178 
00183     struct NodeAttributeCompare
00184     {
00185       NodeAttributeCompare (const char* attributeName)
00186         : attributeName (attributeName)
00187       {
00188       }
00189 
00190       bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
00191       {
00192         if (node1->GetType () != CS_NODE_ELEMENT) return false;
00193         if (node2->GetType () != CS_NODE_ELEMENT) return false;
00194 
00195         csRef<iDocumentAttribute> attribute1 = 
00196           node1->GetAttribute (attributeName.GetData ());
00197         csRef<iDocumentAttribute> attribute2 = 
00198           node2->GetAttribute (attributeName.GetData ());
00199         if (!attribute1 || !attribute2) return false;
00200 
00201         if (!csStrCaseCmp (attribute1->GetValue (), attribute2->GetValue ())) 
00202           return true;
00203 
00204         return false;
00205       }
00206     private:
00207       csString attributeName;
00208     };
00209 
00213     struct NodeValueTest
00214     {
00215       NodeValueTest (const char* value)
00216         : value (value)
00217       {}
00218 
00219       bool operator () (iDocumentNode *node)
00220       {
00221         if (!node) return false;
00222 
00223         const char *nodeValue = node->GetValue ();
00224         return (value == nodeValue);
00225       }
00226 
00227     private:
00228       csString value;
00229     };
00230 
00234     struct NodeAttributeValueTest
00235     {
00236       NodeAttributeValueTest (const char *attribute, const char* value)
00237         : attribute (attribute), value (value)
00238       {}
00239 
00240       bool operator () (iDocumentNode *node)
00241       {
00242         if (!node) return false;
00243 
00244         const char* attributeValue = node->GetAttributeValue (attribute.GetData ());
00245 
00246         return (value == attributeValue);
00247       }
00248 
00249     private:
00250       csString attribute;
00251       csString value;
00252     };
00253 
00258     struct NodeAttributeRegexpTest
00259     {
00260       NodeAttributeRegexpTest (const char *attribute, const char* regexp)
00261         : attribute (attribute), valueMatcher (regexp)
00262       {
00263       }
00264 
00265       bool operator () (iDocumentNode *node)
00266       {
00267         if (!node) return false;
00268 
00269         const char* attributeValue = node->GetAttributeValue (attribute.GetData ());
00270 
00271         return (valueMatcher.Match (attributeValue, csrxIgnoreCase) == csrxNoError);
00272       }
00273 
00274     private:
00275       csString attribute;
00276       csRegExpMatcher valueMatcher;
00277     };
00280 
00281     template<class T>
00282     csPtr<iDocumentNodeIterator> FilterDocumentNodeIterator(
00283       csRef<iDocumentNodeIterator> parent, T filter)
00284     {
00285       return new Implementation::FilterDocumentNodeIterator<T>
00286         (parent, filter);
00287     }
00288   }
00289 }
00290 
00291 #endif

Generated for Crystal Space by doxygen 1.4.4