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