## Public API Reference

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# 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/refarr.h"
    00028 #include "csutil/regexp.h"
    00029 #include "csutil/scf_implementation.h"
    00030
    00031 #include "iutil/document.h"
    00032
    00033 namespace CrystalSpace
    00034 {
    00039   namespace DocumentHelper
    00040   {
    00041     namespace Implementation
    00042     {
    00047       template<class T>
    00048       class FilterDocumentNodeIterator : public
    00049         scfImplementation1 <FilterDocumentNodeIterator<T>,
    00050           iDocumentNodeIterator>
    00051       {
    00052       public:
    00053         FilterDocumentNodeIterator (csRef<iDocumentNodeIterator> parent,
    00054           T filter) : scfImplementation1<FilterDocumentNodeIterator<T>,
    00055             iDocumentNodeIterator> (this), parent (parent), filter (filter)
    00056         {
    00057           ForwardIterator ();
    00058         }
    00059
    00060         // -- iDocumentNodeIterator
    00062         virtual bool HasNext ()
    00063         {
    00064           return nextElement.IsValid ();
    00065         }
    00066
    00068         virtual csRef<iDocumentNode> Next ()
    00069         {
    00070           csRef<iDocumentNode> current = nextElement;
    00071           ForwardIterator ();
    00072           return current;
    00073         }
    00074
    00075       private:
    00076         void ForwardIterator ()
    00077         {
    00078           if (!parent) nextElement = 0;
    00079
    00080           while (parent->HasNext ())
    00081           {
    00082             csRef<iDocumentNode> parentNext = parent->Next ();
    00083             if (filter (parentNext))
    00084             {
    00085               nextElement = parentNext;
    00086               return;
    00087             }
    00088           }
    00089           nextElement = 0;
    00090           parent = 0;
    00091         }
    00092
    00093         csRef<iDocumentNodeIterator> parent;
    00094         T filter;
    00095         csRef<iDocumentNode> nextElement;
    00096       };
    00097     }
    00098
    00105     template<class T>
    00106     void RemoveDuplicateChildren (iDocumentNode *rootNode, T eq)
    00107     {
    00108       csRef<iDocumentNodeIterator> it = rootNode->GetNodes ();
    00109       RemoveDuplicateChildren (rootNode, it, eq);
    00110     }
    00111
    00118     template<class T>
    00119     void RemoveDuplicateChildren (iDocumentNode *rootNode,
    00120       csRef<iDocumentNodeIterator> childIt, T eq)
    00121     {
    00122       typedef csRefArray<iDocumentNode> NodeListType;
    00123       NodeListType nodesToRemove;
    00124       NodeListType nodesToKeep;
    00125
    00126       if (!childIt) return;
    00127
    00128       while (childIt->HasNext ())
    00129       {
    00130         csRef<iDocumentNode> node = childIt->Next ();
    00131         //compare it to those we already have
    00132         bool keep = true;
    00133
    00134         NodeListType::Iterator it = nodesToKeep.GetIterator ();
    00135         while (it.HasNext ())
    00136         {
    00137           csRef<iDocumentNode> keepNode = it.Next ();
    00138           if (keepNode->Equals (node))
    00139           {
    00140             keep = false;
    00141             break;
    00142           }
    00143           if (eq (node, keepNode))
    00144           {
    00145             keep = false;
    00146             break;
    00147           }
    00148         }
    00149
    00150         if (keep)
    00151         {
    00152           nodesToKeep.Push (node);
    00153         }
    00154         else
    00155         {
    00156           nodesToRemove.Push (node);
    00157         }
    00158       }
    00159
    00160       while (nodesToRemove.GetSize ())
    00161       {
    00162         csRef<iDocumentNode> node = nodesToRemove.Pop ();
    00163         rootNode->RemoveNode (node);
    00164       }
    00165     }
    00166
    00173     struct NodeNameCompare
    00174     {
    00175       bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
    00176       {
    00177         if (node1->GetType () != CS_NODE_ELEMENT) return false;
    00178         if (node2->GetType () != CS_NODE_ELEMENT) return false;
    00179
    00180         const char* name1 = node1->GetValue ();
    00181         const char* name2 = node2->GetValue ();
    00182         if (!csStrCaseCmp (name1, name2)) return true;
    00183         return false;
    00184       }
    00185     };
    00186
    00191     struct NodeAttributeCompare
    00192     {
    00193       NodeAttributeCompare (const char* attributeName)
    00194         : attributeName (attributeName)
    00195       {
    00196       }
    00197
    00198       bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
    00199       {
    00200         if (node1->GetType () != CS_NODE_ELEMENT) return false;
    00201         if (node2->GetType () != CS_NODE_ELEMENT) return false;
    00202
    00203         csRef<iDocumentAttribute> attribute1 =
    00204           node1->GetAttribute (attributeName.GetData ());
    00205         csRef<iDocumentAttribute> attribute2 =
    00206           node2->GetAttribute (attributeName.GetData ());
    00207         if (!attribute1 || !attribute2) return false;
    00208
    00209         if (!csStrCaseCmp (attribute1->GetValue (), attribute2->GetValue ()))
    00210           return true;
    00211
    00212         return false;
    00213       }
    00214     private:
    00215       csString attributeName;
    00216     };
    00217
    00221     struct NodeValueTest
    00222     {
    00223       NodeValueTest (const char* value)
    00224         : value (value)
    00225       {}
    00226
    00227       bool operator () (iDocumentNode *node)
    00228       {
    00229         if (!node) return false;
    00230
    00231         const char *nodeValue = node->GetValue ();
    00232         return (value == nodeValue);
    00233       }
    00234
    00235     private:
    00236       csString value;
    00237     };
    00238
    00242     struct NodeAttributeValueTest
    00243     {
    00244       NodeAttributeValueTest (const char *attribute, const char* value)
    00245         : attribute (attribute), value (value)
    00246       {}
    00247
    00248       bool operator () (iDocumentNode *node)
    00249       {
    00250         if (!node) return false;
    00251
    00252         const char* attributeValue = node->GetAttributeValue (
    00253                 attribute.GetData ());
    00254
    00255         return (value == attributeValue);
    00256       }
    00257
    00258     private:
    00259       csString attribute;
    00260       csString value;
    00261     };
    00262
    00267     struct NodeAttributeRegexpTest
    00268     {
    00269       NodeAttributeRegexpTest (const char *attribute, const char* regexp)
    00270         : attribute (attribute), valueMatcher (regexp)
    00271       {
    00272       }
    00273
    00274       bool operator () (iDocumentNode *node)
    00275       {
    00276         if (!node) return false;
    00277
    00278         const char* attributeValue = node->GetAttributeValue (
    00279                 attribute.GetData ());
    00280
    00281         return (valueMatcher.Match (attributeValue, csrxIgnoreCase)
    00282                 == csrxNoError);
    00283       }
    00284
    00285     private:
    00286       csString attribute;
    00287       csRegExpMatcher valueMatcher;
    00288     };
    00302     template<class T>
    00303     csPtr<iDocumentNodeIterator> FilterDocumentNodeIterator(
    00304       csRef<iDocumentNodeIterator> parent, T filter)
    00305     {
    00306       return new Implementation::FilterDocumentNodeIterator<T>
    00307         (parent, filter);
    00308     }
    00309   }
    00310 }
    00311
    00312 #endif