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