## 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/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