Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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 {
00037 namespace DocSystem
00038 {
00039 namespace Implementation
00040 {
00045 template<class T>
00046 class FilterDocumentNodeIterator : public
00047 scfImplementation1 <FilterDocumentNodeIterator<T>,
00048 iDocumentNodeIterator>
00049 {
00050 public:
00051 FilterDocumentNodeIterator (csRef<iDocumentNodeIterator> parent,
00052 T filter) : scfImplementation1<FilterDocumentNodeIterator<T>,
00053 iDocumentNodeIterator> (this), parent (parent), filter (filter)
00054 {
00055 ForwardIterator ();
00056 }
00057
00058
00060 virtual bool HasNext ()
00061 {
00062 return nextElement.IsValid ();
00063 }
00064
00066 virtual csRef<iDocumentNode> Next ()
00067 {
00068 csRef<iDocumentNode> current = nextElement;
00069 ForwardIterator ();
00070 return current;
00071 }
00072
00073 virtual size_t GetNextPosition ()
00074 {
00075 if (nextElement.IsValid ())
00076 return parent->GetNextPosition ();
00077 else
00078 return parent->GetEndPosition ();
00079 }
00080
00081 virtual size_t GetEndPosition ()
00082 { return parent->GetEndPosition (); }
00083
00084 private:
00085 void ForwardIterator ()
00086 {
00087 if (!parent) nextElement = 0;
00088
00089 while (parent->HasNext ())
00090 {
00091 csRef<iDocumentNode> parentNext = parent->Next ();
00092 if (filter (parentNext))
00093 {
00094 nextElement = parentNext;
00095 return;
00096 }
00097 }
00098 nextElement = 0;
00099 parent = 0;
00100 }
00101
00102 csRef<iDocumentNodeIterator> parent;
00103 T filter;
00104 csRef<iDocumentNode> nextElement;
00105 };
00106 }
00107
00114 template<class T>
00115 void RemoveDuplicateChildren (iDocumentNode *rootNode, T eq)
00116 {
00117 csRef<iDocumentNodeIterator> it = rootNode->GetNodes ();
00118 RemoveDuplicateChildren (rootNode, it, eq);
00119 }
00120
00127 template<class T>
00128 void RemoveDuplicateChildren (iDocumentNode *rootNode,
00129 csRef<iDocumentNodeIterator> childIt, T eq)
00130 {
00131 typedef csRefArray<iDocumentNode> NodeListType;
00132 NodeListType nodesToRemove;
00133 NodeListType nodesToKeep;
00134
00135 if (!childIt) return;
00136
00137 while (childIt->HasNext ())
00138 {
00139 csRef<iDocumentNode> node = childIt->Next ();
00140
00141 bool keep = true;
00142
00143 NodeListType::Iterator it = nodesToKeep.GetIterator ();
00144 while (it.HasNext ())
00145 {
00146 csRef<iDocumentNode> keepNode = it.Next ();
00147 if (keepNode->Equals (node))
00148 {
00149 keep = false;
00150 break;
00151 }
00152 if (eq (node, keepNode))
00153 {
00154 keep = false;
00155 break;
00156 }
00157 }
00158
00159 if (keep)
00160 {
00161 nodesToKeep.Push (node);
00162 }
00163 else
00164 {
00165 nodesToRemove.Push (node);
00166 }
00167 }
00168
00169 while (nodesToRemove.GetSize ())
00170 {
00171 csRef<iDocumentNode> node = nodesToRemove.Pop ();
00172 rootNode->RemoveNode (node);
00173 }
00174 }
00175
00181 inline void CloneAttributes (iDocumentNode* from, iDocumentNode* to)
00182 {
00183 csRef<iDocumentAttributeIterator> atit = from->GetAttributes ();
00184 while (atit->HasNext ())
00185 {
00186 csRef<iDocumentAttribute> attr = atit->Next ();
00187 to->SetAttribute (attr->GetName (), attr->GetValue ());
00188 }
00189 }
00190
00196 inline void CloneNode (iDocumentNode* from, iDocumentNode* to)
00197 {
00198 to->SetValue (from->GetValue ());
00199 csRef<iDocumentNodeIterator> it = from->GetNodes ();
00200 while (it->HasNext ())
00201 {
00202 csRef<iDocumentNode> child = it->Next ();
00203 csRef<iDocumentNode> child_clone = to->CreateNodeBefore (
00204 child->GetType (), 0);
00205 CloneNode (child, child_clone);
00206 }
00207 CloneAttributes (from, to);
00208 }
00209
00216 struct NodeNameCompare
00217 {
00218 bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
00219 {
00220 if (node1->GetType () != CS_NODE_ELEMENT) return false;
00221 if (node2->GetType () != CS_NODE_ELEMENT) return false;
00222
00223 const char* name1 = node1->GetValue ();
00224 const char* name2 = node2->GetValue ();
00225 if (!csStrCaseCmp (name1, name2)) return true;
00226 return false;
00227 }
00228 };
00229
00234 struct NodeAttributeCompare
00235 {
00236 NodeAttributeCompare (const char* attributeName)
00237 : attributeName (attributeName)
00238 {
00239 }
00240
00241 bool operator () (iDocumentNode *node1, iDocumentNode *node2) const
00242 {
00243 if (node1->GetType () != CS_NODE_ELEMENT) return false;
00244 if (node2->GetType () != CS_NODE_ELEMENT) return false;
00245
00246 csRef<iDocumentAttribute> attribute1 =
00247 node1->GetAttribute (attributeName.GetData ());
00248 csRef<iDocumentAttribute> attribute2 =
00249 node2->GetAttribute (attributeName.GetData ());
00250 if (!attribute1 || !attribute2) return false;
00251
00252 if (!csStrCaseCmp (attribute1->GetValue (), attribute2->GetValue ()))
00253 return true;
00254
00255 return false;
00256 }
00257 private:
00258 csString attributeName;
00259 };
00260
00264 struct NodeValueTest
00265 {
00266 NodeValueTest (const char* value)
00267 : value (value)
00268 {}
00269
00270 bool operator () (iDocumentNode *node)
00271 {
00272 if (!node) return false;
00273
00274 const char *nodeValue = node->GetValue ();
00275 return (value == nodeValue);
00276 }
00277
00278 private:
00279 csString value;
00280 };
00281
00285 struct NodeAttributeValueTest
00286 {
00287 NodeAttributeValueTest (const char *attribute, const char* value)
00288 : attribute (attribute), value (value)
00289 {}
00290
00291 bool operator () (iDocumentNode *node)
00292 {
00293 if (!node) return false;
00294
00295 const char* attributeValue = node->GetAttributeValue (
00296 attribute.GetData ());
00297
00298 return (value == attributeValue);
00299 }
00300
00301 private:
00302 csString attribute;
00303 csString value;
00304 };
00305
00310 struct NodeAttributeRegexpTest
00311 {
00312 NodeAttributeRegexpTest (const char *attribute, const char* regexp)
00313 : attribute (attribute), valueMatcher (regexp)
00314 {
00315 }
00316
00317 bool operator () (iDocumentNode *node)
00318 {
00319 if (!node) return false;
00320
00321 const char* attributeValue = node->GetAttributeValue (
00322 attribute.GetData ());
00323
00324 return (valueMatcher.Match (attributeValue, csrxIgnoreCase)
00325 == csrxNoError);
00326 }
00327
00328 private:
00329 csString attribute;
00330 csRegExpMatcher valueMatcher;
00331 };
00346 template<class T>
00347 csPtr<iDocumentNodeIterator> FilterDocumentNodeIterator(
00348 csRef<iDocumentNodeIterator> parent, T filter)
00349 {
00350 return new Implementation::FilterDocumentNodeIterator<T>
00351 (parent, filter);
00352 }
00353
00358 CS_CRYSTALSPACE_EXPORT csString FlattenNode (iDocumentNode* node);
00363 CS_CRYSTALSPACE_EXPORT csString FlattenNodeShallow (iDocumentNode* node);
00364
00372 CS_CRYSTALSPACE_EXPORT csPtr<iDocument> MakeChangeable (iDocument* doc,
00373 iDocumentSystem* docsys);
00374
00383 CS_CRYSTALSPACE_EXPORT bool SetContentsValue (iDocumentNode* node,
00384 const char* contents);
00385 }
00386
00387
00388 }
00389
00390 #endif