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
Generated for Crystal Space by doxygen 1.4.6