Spinning Topp Logo BlackTopp Studios
inc
node.h
Go to the documentation of this file.
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 /*
41  *
42  * Software, Files, Libraries and all other items referenced in this clause refers only
43  * to the contents of this file and associated documentation.
44  *
45  * Pugixml parser - version 1.0
46  * --------------------------------------------------------
47  * Copyright © 2006-2012, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
48  * Report bugs and download new versions at http://pugixml.org/
49  *
50  * This library is distributed under the MIT License. See notice at the end
51  * of this file.
52  *
53  * This work is based on the pugxml parser, which is:
54  * Copyright © 2003, by Kristen Wegner (kristen@tima.net)
55  */
56 
57 #ifndef _xmlnode_h
58 #define _xmlnode_h
59 
60 /// @file
61 /// @brief This defines the @ref Mezzanine::XML::Node one of the central XML classes.
62 
63 #include "datatypes.h"
64 #include "XML/xmlenumerations.h"
65 #include "XML/attribute.h"
66 #include "XML/objectrange.h"
67 
68 
69 
70 namespace Mezzanine
71 {
72  namespace XML
73  {
74  class NodeStruct;
75  class NodeText;
76  class TreeWalker;
77  class XPathNode;
78  class XPathNodeSet;
79  class XPathVariableSet;
80  class XPathQuery;
81  class Writer;
82  class NodeIterator;
83  class AttributeIterator;
84  class NamedNodeIterator;
85 
86 
87 
88  /// @brief A light-weight handle for manipulating nodes in DOM tree.
89  class MEZZ_LIB Node
90  {
91  friend class AttributeIterator;
92  friend class NodeIterator;
93  friend class NamedNodeIterator;
94 
95  protected:
96  /// @internal
97  /// @brief Stores pointers to the Node data and some metadata.
98  NodeStruct* NodeData;
99 
100  #ifndef SWIG
101  /// @brief Used to prevent casting to numerical types acccidentally.
102  /// @note Not available in scripting languages because conversion is handled on a per langauge basis.
103  typedef void (*unspecified_bool_type)(Node***);
104  #endif
105 
106  public:
107  /// @brief Default constructor. Constructs an empty node.
108  Node();
109 
110  /// @brief Virtual deconstructor.
111  ~Node();
112 
113  /// @brief Constructs node from internal pointer
114  /// @param p An internal node pointer.
115  explicit Node(NodeStruct* p);
116 
117  #ifndef SWIG
118  /// @brief Used to convert this to a boolean value in a safe way
119  /// @return Returns true if the internal data is set and false otherwise.
120  /// @note Not available in scripting languages because conversion is handled on a per langauge basis.
121  operator unspecified_bool_type() const;
122  #endif
123 
124  /// @brief Used to convert this node the opposite of it's normal boolean value
125  /// @details This is described in the PugiXML source a a workaround for a borland c++ issue.
126  /// @return Returns false if the internal pointer NodeStruct is set and true otherwise.
127  bool operator!() const;
128 
129 #if !(defined(SWIG) && defined(MEZZLUA51)) // Stop Swig from making lua bindings but allow other languages
130  /// @brief Compares the internal values to check equality.
131  /// @param r The other @ref Node this is being compared to.
132  /// @details Many of the internal values are pointers, and it is the addresses of these that are being compared.
133  /// @return Returns true if all the internal values match between this and the other Node.
134  /// @note Not available in scripting languages
135  bool operator==(const Node& r) const;
136 #endif
137 
138  /// @brief Compares the internal values to check inequality.
139  /// @param r The other @ref Node this is being compared to.
140  /// @details Many of the internal values are pointers, and it is the addresses of these that are being compared.
141  /// @return Returns true if any of the internal values don't match between this and the other @ref Node.
142  bool operator!=(const Node& r) const;
143 
144  /// @brief Compares the internal values to check for lessthanness.
145  /// @param r The other @ref Node this is being compared to.
146  /// @details Many of the internal values are pointers, and it is the addresses of these that are being compared.
147  /// @return Returns True if the other @ref Node is greater than this one as per sequential comparison of internal pointers.
148  bool operator<(const Node& r) const;
149 
150  /// @brief Compares the internal values to check for greaterthanness.
151  /// @param r The other @ref Node this is being compared to.
152  /// @details Many of the internal values are pointers, and it is the addresses of these that are being compared.
153  /// @return Returns True if the other @ref Node is less than this one as per sequential comparison of internal pointers.
154  bool operator>(const Node& r) const;
155 
156  /// @brief Compares the internal values to check for inequality and lessthanness.
157  /// @param r The other @ref Node this is being compared to.
158  /// @details Many of the internal values are pointers, and it is the addresses of these that are being compared.
159  /// @return Returns True if the other @ref Node is greater than or equal to this one as per sequential comparison of internal pointers.
160  bool operator<=(const Node& r) const;
161 
162  /// @brief Compares the internal values to check for inequality and greaterthanness.
163  /// @param r The other @ref Node this is being compared to.
164  /// @details Many of the internal values are pointers, and it is the addresses of these that are being compared.
165  /// @return Returns True if the other @ref Node is less than or equal to this one as per sequential comparison of internal pointers.
166  bool operator>=(const Node& r) const;
167 
168  /// @brief Is this storing anything at all?
169  /// @return Returns True if this @ref Node is storing nothing. False if it is storing anything.
170  bool Empty() const;
171 
172  /// @brief Identify what kind of Node this is.
173  /// @return A @ref NodeType identifying this Node, or o/NULL if this Node is empty.
174  NodeType Type() const;
175 
176  /// @brief ptrdiff_tGet the name of this @ref Node.
177  /// @return Returns A pointer to a const c-style array of the the character type (usually char or wchar_t) containing the name.
178  /// @warning returns "" if Node is empty.
179  const Char8* Name() const;
180 
181  /// @brief Get the Value of this @ref Node.
182  /// @return Returns A pointer to a const c-style array of the the character type (usually char or wchar_t) containing the value.
183  /// @warning returns "" if Node is empty.
184  const Char8* Value() const;
185 
186  /// @brief Get the First Attribute in this Node.
187  /// @return This attempts to return the First @ref Attribute in this node, if it cannot it returns an empty @ref Attribute.
188  Attribute GetFirstAttribute() const;
189 
190  /// @brief Get the Last Attribute in this Node.
191  /// @return This attempts to return the Last @ref Attribute in this node, if it cannot it returns an empty @ref Attribute.
192  Attribute GetLastAttribute() const;
193 
194  /// @brief Get the first child Node of this Node.
195  /// @return Returns the First child node if it exists, otherwise it return an empty node.
196  Node GetFirstChild() const;
197 
198  /// @brief Get the last child Node of this Node.
199  /// @return Returns the last child node if it exists, otherwise it return an empty node.
200  Node GetLastChild() const;
201 
202  /// @brief Attempt to retrieve the next sibling of this Node.
203  /// @details A sibling of a Node is another Node that shares the same parent. If this is and the sibling nodes are valid, this retrieves that Node, otherwise this return an empty Node.
204  /// @return A Node that represents a sibling, or an empty Node on failure.
205  Node GetNextSibling() const;
206 
207  /// @brief Attempt to retrieve the prvious sibling of this Node.
208  /// @details A sibling of a Node is another Node that shares the same parent. If this is and the sibling nodes are valid, this retrieves that Node, otherwise this return an empty Node.
209  /// @return A Node that represents a sibling, or an empty Node on failure.
210  Node GetPreviousSibling() const;
211 
212  /// @brief Attempt to retrieve the parent of this Node.
213  /// @return A Node that represents the parent Node, or an empty Node on failure.
214  Node GetParent() const;
215 
216  /// @brief Attempt to retrieve the root Node, or the most base Node containing this Node.
217  /// @return A Node that represents the root of the XML document, or an empty Node on failure. If there are multiple roots this attempts to retrieve the appropriate one.
218  Node GetRoot() const;
219 
220  /// @brief Get text object for the current node
221  /// @return An @ref Mezzanine::XML::NodeText which represents the PCData of this node.
222  NodeText GetText() const;
223 
224 #if !(defined(SWIG) && defined(MEZZLUA51)) // Stop Swig from making lua bindings but allow other languages
225  /// @brief Attempt to get a child Node with a given name.
226  /// @param Name The name of the desired child Node.
227  /// @return A Node that represents the first desired child, or an empty Node on failure.
228  /// @note Not available in scripting languages in favor of the overload of this function that accepts String as a parameter.
229  Node GetChild(const Char8* Name) const;
230 #endif
231 
232  /// @brief Attempt to get a child Node with a given name.
233  /// @param Name The name of the desired child Node.
234  /// @return A Node that represents the first desired child, or an empty Node on failure.
235  Node GetChild(const String& Name) const
236  { return GetChild(Name.c_str()); }
237 
238  /// @brief Attempt to get an Attribute on this Node with a given name.
239  /// @param Name The name of the desired Attribute.
240  /// @return An Attribute that represents the first matching Attribute, or an empty Attribute on failure.
241  Attribute GetAttribute(const Char8* Name) const;
242 
243  /// @brief Like @ref GetNextSibling except that the return will be a null Node or have a matching name.
244  /// @param Name if possible this will return the next sibling with this name.
245  /// @return The next sibling with a matching name, or a null/empty node.
246  Node GetNextSibling(const Char8* Name) const;
247 
248  /// @brief Like @ref GetPreviousSibling except that the return will be a null Node or have a matching name.
249  /// @param Name if possible this will return the previous sibling with this name.
250  /// @return The previous sibling with a matching name, or a null/empty node.
251  Node GetPreviousSibling(const Char8* Name) const;
252 
253  /// @brief Retrieve the value of this(or a child's) Nodes PCDATA child Node
254  /// @details If this node represents "<node>Some text in the PCDATA field, that is actually represent by a node</node>", then this would return "Some text in the PCDATA field, that is actually represent by a node". This will iterate through child Nodes from until it finds a PCDATA node or fails
255  /// @return This will return the Value of the first available PCDATA node.
256  const Char8* GetChildValue() const;
257 
258  /// @brief Get the PCDATA of a given child. The same a calling "GetChild(Name).ChildValue()".
259  /// @param Name The Name of the desired child node.
260  /// @return This will return the Value of the first available matching PCDATA node.
261  const Char8* GetChildValue(const Char8* Name) const;
262 
263  #ifndef SWIG
264  /// @brief Set the name of .
265  /// @param rhs The desired name.
266  /// @return True if successful, returns false if the name cannot be stored or there is not enough memory.
267  /// @note Not available in scripting languages in favor of the overload of this function that accepts String as a parameter.
268  bool SetName(const Char8* rhs);
269  #endif
270 
271  /// @brief Set the name of this object
272  /// @param rhs The desired name .
273  /// @return True if successful, returns false if the name cannot be stored or there is not enough memory.
274  bool SetName(const String& rhs)
275  { return SetName(rhs.c_str()); }
276 
277  /// @brief Set the value of this.
278  /// @param rhs The new Value.
279  /// @return True if successful, returns false if this is empty or there is not enough memory.
280  /// @todo update this to make the error return code redundant and use an exception instead.
281  /// @todo Review for possiblity of buffer overflow.
282  bool SetValue(const Char8* rhs);
283 
284 #if !(defined(SWIG) && defined(MEZZLUA51)) // Stop Swig from making lua bindings but allow other languages
285  /// @brief Creates an Attribute and puts it at the end of this Nodes attributes.
286  /// @param Name The name of the New attribute to be created
287  /// @details This attempts to create an Attribute and stick it at the end of the list of attribute on the current
288  /// Node. This will fail and return an Empty Attribute if this Node is neither an Element nor a Declaration. This will
289  /// fail and return an empty attribute if this Node is empty.
290  /// @return The created Attribute or an empty Attribute on Failure.
291  /// @note Not available in scripting languages in favor of the overload of this function that accepts String as a parameter.
292  Attribute AppendAttribute(const Char8* Name);
293 #endif
294 
295  /// @brief Creates an Attribute and puts it at the end of this Nodes attributes.
296  /// @param Name The name of the New attribute to be created
297  /// @return The created Attribute or an empty Attribute on Failure.
299  { return AppendAttribute(Name.c_str()); }
300 
301  /// @brief Creates an Attribute and puts it at the begining of this Nodes attributes
302  /// @param Name The name of the New attribute to be created
303  /// @details This attempts to create an Attribute and stick it at the beginning of the list of attributes on the current
304  /// Node. This will fail and return an Empty Attribute if this Node is neither an Element nor a Declaration. This will
305  /// fail and return an empty attribute if this Node is empty.
306  /// @return The created Attribute or an empty Attribute on Failure.
307  Attribute PrependAttribute(const Char8* Name);
308 
309  /// @brief Creates an Attribute and puts it into the list of this Nodes attributes.
310  /// @param Name The name of the New attribute to be created
311  /// @param attr An Attribute that represents an Attribute on this Node, and is just before where you want the new Attribute.
312  /// @details This attempts to create an Attribute and stick it in the list of attributes, Just after another Attribute, on the current
313  /// Node. This will fail and return an Empty Attribute if this Node is neither an Element nor a Declaration. This will
314  /// fail and return an empty attribute if this Node is empty.
315  /// @return The created Attribute or an empty Attribute on Failure.
316  Attribute InsertAttributeAfter(const Char8* Name, const Attribute& attr);
317 
318  /// @brief Creates an Attribute and puts it into the list of this Nodes attributes.
319  /// @param Name The name of the New attribute to be created
320  /// @param attr An Attribute that represents an Attribute on this Node, and is just after where you want the new Attribute.
321  /// @details This attempts to create an Attribute and stick it in the list of attributes, Just before another Attribute, on the current
322  /// Node. This will fail and return an Empty Attribute if this Node is neither an Element nor a Declaration. This will
323  /// fail and return an empty attribute if this Node is empty.
324  /// @return The created Attribute or an empty Attribute on Failure.
325  Attribute InsertAttributeBefore(const Char8* Name, const Attribute& attr);
326 
327  /// @brief Copies an Attribute and puts the copy at the end of this Nodes attributes.
328  /// @param proto The attribute to be copied.
329  /// @details This attempts to create a copy of an attribute Attribute and stick it at the end of the list of attribute on the current
330  /// Node. This will fail and return an Empty Attribute if this Node is neither an Element nor a Declaration. This will
331  /// fail and return an empty attribute if this Node is empty.
332  /// @return The created Attribute or an empty Attribute on Failure.
333  Attribute AppendCopy(const Attribute& proto);
334 
335  /// @brief Copies an Attribute and puts the copy at the beginning of this Nodes attributes.
336  /// @param proto The attribute to be copied.
337  /// @details This attempts to create a copy of an attribute Attribute and stick it at the beginning of the list of attribute on the current
338  /// Node. Tptrdiff_this will fail and return an Empty Attribute if this Node is neither an Element nor a Declaration. This will
339  /// fail and return an empty attribute if this Node is empty.
340  /// @return The created Attribute or an empty Attribute on Failure.
341  Attribute PrependCopy(const Attribute& proto);
342 
343  /// @brief Copies an Attribute and puts the copy into the list of this Nodes attributes.
344  /// @param proto The attribute to be copied.
345  /// @param attr An Attribute that represents an Attribute on this Node, and is just before where you want the new copy of proto.
346  /// @details This attempts to create a copy of an attribute Attribute and stick it in the middle of the list of attributes, just after a selected attribute, on the current
347  /// Node. This will fail and return an Empty Attribute if this Node is neither an Element nor a Declaration. This will
348  /// fail and return an empty attribute if this Node is empty.
349  /// @return The created Attribute or an empty Attribute on Failure.
350  Attribute InsertCopyAfter(const Attribute& proto, const Attribute& attr);
351 
352  /// @brief Copies an Attribute and puts the copy into the list of this Nodes attributes.
353  /// @param proto The attribute to be copied.
354  /// @param attr An Attribute that represents an Attribute on this Node, and is just after where you want the new copy of proto.
355  /// @details This attempts to create a copy of an attribute Attribute and stick it in the middle of the list of attributes, just before a selected attribute, on the current
356  /// Node. This will fail and return an Empty Attribute if this Node is neither an Element nor a Declaration. This will
357  /// fail and return an empty attribute if this Node is empty.
358  /// @return The created Attribute or an empty Attribute on Failure.
359  Attribute InsertCopyBefore(const Attribute& proto, const Attribute& attr);
360 
361  /// @brief Creates a Node and makes it a child of this one.
362  /// @param Type The NodeType of the Node to be added to list of child Nodes.
363  /// @return A Node representing the freshly added Node, or an empty Node if there was an error.
364  Node AppendChild(NodeType Type = NodeElement);
365 
366  /// @brief Creates a Node and makes it a child of this one, and puts at the beginning of the Child Nodes.
367  /// @param Type The NodeType of the Node to be added to the beginning list of child Nodes.
368  /// @return A Node representing the freshly added Node, or an empty Node if there was an error.
369  /// @todo Not all nodes can be added to other nodes, we need to figure it out and put it here.
370  Node PrependChild(NodeType Type = NodeElement);
371 
372  /// @brief Creates a Node and makes it a child of this one, and puts at the middle of the Child Nodes.
373  /// @param Type The NodeType of the Node to be added, just after another specific node.
374  /// @param node The specific node to add the new one after.
375  /// @todo Not all nodes can be added to other nodes, we need to figure it out and put it here.
376  /// @return A Node representing the freshly added Node, or an empty Node if there was an error.
377  Node InsertChildAfter(NodeType Type, const Node& node);
378 
379  /// @brief Creates a Node and makes it a child of this one, and puts at the middle of the Child Nodes.
380  /// @param Type The NodeType of the Node to be added, just before another specific node.
381  /// @param node The specific node to add the new one before.
382  /// @return A Node representing the freshly added Node, or an empty Node if there was an error.
383  /// @todo Not all nodes can be added to other nodes, we need to figure it out and put it here.
384  Node InsertChildBefore(NodeType Type, const Node& node);
385 
386 #if !(defined(SWIG) && defined(MEZZLUA51)) // Stop Swig from making lua bindings but allow other languages
387  /// @brief Creates an element Node as a child of this Node, with the given name.
388  /// @param Name The name of the Node to be created.
389  /// @details Calls @ref Node::AppendChild(NodeType); using NodeElement as the NodeType.
390  /// @return The desired Node on success, an empty Node on failure.
391  /// @note Not available in scripting languages in favor of the overload of this function that accepts String as a parameter.
392  Node AppendChild(const Char8* Name);
393 #endif
394 
395  /// @brief Creates an element Node as a child of this Node, with the given name.
396  /// @param Name The name of the Node to be created.
397  /// @details Calls @ref Node::AppendChild
398  /// @return The desired Node on success, an empty Node on failure.
399  Node AppendChild(const String& Name)
400  { return AppendChild(Name.c_str()); }
401 
402 #if !(defined(SWIG) && defined(MEZZLUA51)) // Stop Swig from making lua bindings but allow other languages
403  /// @brief Creates an element Node as a child of this Node, with the given name at the beginning of the children
404  /// @param Name The name of the Node to be created.
405  /// @details Calls @ref Node::PrependChild(NodeType); using NodeElement as the NodeType.
406  /// @return The desired Node on success, an empty Node on failure.
407  /// @note Not available in scripting languages in favor of the overload of this function that accepts String as a parameter.
408  Node PrependChild(const Char8* Name);
409 #endif
410 
411  /// @brief Creates an element Node as a child of this Node, with the given name at the beginning of the children
412  /// @param Name The name of the Node to be created.
413  /// @details Calls @ref Node::PrependChild
414  /// @return The desired Node on success, an empty Node on failure.
415  Node PrependChild(const String& Name)
416  { return PrependChild(Name.c_str()); }
417 
418  /// @brief Creates an element Node as a child of this Node, with the given name at the middle of the children
419  /// @param Name The name of the Node to be created.
420  /// @param node The node just before were the Create node is to be placed.
421  /// @details Calls Node::InsertChildAfter(NodeType, Node); using NodeElement as the NodeType.
422  /// @return The desired Node on success, an empty Node on failure.
423  Node InsertChildAfter(const Char8* Name, const Node& node);
424 
425  /// @brief Creates an element Node as a child of this Node, with the given name at the middle of the children
426  /// @param Name The name of the Node to be created.
427  /// @param node The node just after were the Create node is to be placed.
428  /// @details Calls Node::InsertChildBefore(NodeType, Node); using NodeElement as the NodeType.
429  /// @return The desired Node on success, an empty Node on failure.
430  Node InsertChildBefore(const Char8* Name, const Node& node);
431 
432  /// @brief Copies a Node and puts the copy at the end of the list of this Nodes Childrem.
433  /// @param proto The Node to be copied. If this is emptry, no work is performed.
434  /// @return The copied Node on success, an empty Node on failure.
435  Node AppendCopy(const Node& proto);
436 
437  /// @brief Copies a Node and puts the copy at the start of the list of this Nodes Childrem.
438  /// @param proto The Node to be copied. If this is emptry, no work is performed.
439  /// @return The copied Node on success, an empty Node on failure.
440  Node PrependCopy(const Node& proto);
441 
442  /// @brief Copies a Node and puts the copy in the middle the list of this Nodes Childrem.
443  /// @param proto The Node to be copied. If this is emptry, no work is performed.
444  /// @param node The Node just before the desired place in the list of children to insert the copied node.
445  /// @return The copied Node on success, an empty Node on failure.
446  Node InsertCopyAfter(const Node& proto, const Node& node);
447 
448  /// @brief Copies a Node and puts the copy in the middle the list of this Nodes Childrem.
449  /// @param proto The Node to be copied. If this is emptry, no work is performed.
450  /// @param node The Node just after the desired place in the list of children to insert the copied node.
451  /// @return The copied Node on success, an empty Node on failure.
452  Node InsertCopyBefore(const Node& proto, const Node& node);
453 
454  /// @brief Remove specified Attribute.
455  /// @param a The Attribute to look for. If the given Attribute doesn't belong to this Node then this will fail
456  /// @return True if the removal was successful, false otherwise.
457  bool RemoveAttribute(const Attribute& a);
458 
459  /// @brief Remove Attribute as specified by name.
460  /// @param Name The name of the Attribute to remove.
461  /// @return True if the removal was successful, false otherwise.
462  bool RemoveAttribute(const Char8* Name);
463 
464  /// @brief Remove specified child element.
465  /// @param n The Node to look for. If the given Attribute doesn't belong to this Node then this will fail
466  /// @return True if the removal was successful, false otherwise.
467  bool RemoveChild(const Node& n);
468 
469  /// @brief Remove child element as specified by name.
470  /// @param Name The name of the Node to remove.
471  /// @return True if the removal was successful, false otherwise
472  bool RemoveChild(const Char8* Name);
473 
474  /// @brief Search for an Attribute using a function to check each Attribute individually.
475  /// @param pred a pointer to a function that accepts an Attribute, and returns bool.
476  /// @details This iterates through each Attribute on this node, from begining to end and calls the Predicate function passing
477  /// an Attribute to it. If the Predicate returns true the Node it was just passed is returned. If Precdicate never returns
478  /// true, it is called on every Node and a blank Node is returned. The Predicate is never called with a null value.
479  /// @return This returns the first Attribute that causes Predicate to return true.
480  template <typename Predicate> Attribute FindAttribute(Predicate pred) const
481  {
482  if (!NodeData) return Attribute();
483 
484  for (Attribute attrib = GetFirstAttribute(); attrib; attrib = attrib.GetNextAttribute())
485  if (pred(attrib))
486  return attrib;
487 
488  return Attribute();
489  }
490 
491 
492  /// @brief Search for an child ( only direct children ) Node using a function to check each Node individually.
493  /// @param pred a pointer to a function that accepts an Node, and returns bool.
494  /// @details This iterates through all immediate children of this Node and calls the Predicate function passing a Node to it. If
495  /// the Predicate returns true the Node it was just passed is returned. If Predicate never returns true, it is called
496  /// on every Node and a blank Node is returned. The Predicate is never called with a null value.
497  /// @return This returns the first Node that causes Predicate to return true.
498  template <typename Predicate> Node FindChild(Predicate pred) const
499  {
500  if (!NodeData) return Node();
501 
502  for (Node node = GetFirstChild(); node; node = node.GetNextSibling())
503  if (pred(node))
504  return node;
505 
506  return Node();
507  }
508 
509  /// @brief Search for any Node descended from this Node using a function to check each Node individually.
510  /// @param pred a pointer to a function that accepts an Node, and returns bool.
511  /// @details This iterates through all children of this Node, and their children ( and so on), and calls the Predicate function
512  /// passing each Node to it. This iterates through all Nodes using a depth first algorithm. If the Predicate returns true the
513  /// Node it was just passed is returned. If Predicate never returns true, it is called on every Node and a blank Node is
514  /// returned. The Predicate is never called with a null value.
515  /// @return This returns the first Node that causes Predicate to return true.
516  template <typename Predicate> Node FindNode(Predicate pred) const
517  {
518  if (!NodeData) return Node();
519 
520  Node cur = GetFirstChild();
521  while (cur.NodeData && cur.NodeData != NodeData)
522  {
523  if (pred(cur)) return cur;
524 
525  if (cur.GetFirstChild()) cur = cur.GetFirstChild();
526  else if (cur.GetNextSibling()) cur = cur.GetNextSibling();
527  else
528  {
529  while (!cur.GetNextSibling() && cur.NodeData != NodeData) cur = cur.GetParent();
530 
531  if (cur.NodeData != NodeData) cur = cur.GetNextSibling();
532  }
533  }
534 
535  return Node();
536  }
537 
538  /// @brief Find a Node by an Attribute it has.
539  /// @param Name The name of the matching Node.
540  /// @param AttrName The name of the matching Attribute.
541  /// @param AttrValue The value of the matching Attribute.
542  /// @details Any Null pointers instead of character arrays passed in will cause undefined behavior. All Matching is Case sensitive.
543  /// @return The First matching XML::Node
544  Node FindChildbyAttribute(const Char8* Name, const Char8* AttrName, const Char8* AttrValue) const;
545 
546  /// @brief Find a Node by an Attribute it has.
547  /// @param AttrName The name of the matching Attribute.
548  /// @param AttrValue The value of the matching Attribute.
549  /// @details Any Null pointers instead of character arrays passed in will cause undefined behavior. All Matching is Case sensitive.
550  /// @return The First matching XML::Node
551  Node FindChildbyAttribute(const Char8* AttrName, const Char8* AttrValue) const;
552 
553  /// @brief Get the absolute path to this Node
554  /// @param delimiter The character to use as a pathname separator, this defaults to '/'.
555  /// @return A String containing an path
556  String Path(Char8 delimiter = '/') const;
557 
558  /// @brief Search for a node by Path consisting of node names and . or .. elements.
559  /// @todo Investigate this more deeply.
560  /// @param Path The path to search for.
561  /// @param delimiter The character to use as a pathname separator, this defaults to '/'.
562  /// @return The matching Node, of an empty Node on failure.
563  Node FirstElementByPath(const Char8* Path, Char8 delimiter = '/') const;
564 
565  /// @brief Perform sophisticated (or whatever) algorithms on this and all descendant Nodes in the XML tree.
566  /// @param walker Any class that fully implement XML::Treewalker. This is where the algorithm to be run is located.
567  /// @return True if every descendant Node of this Node was iterated through, false if it didn't go through every Node.
568  /// @see XML::TreeWalker
569  bool Traverse(TreeWalker& walker);
570 
571  /// @brief Select single node by evaluating an XPath query. Returns first node from the resulting node set.
572  /// @param query The XPath query as a c-string to be evaluated.
573  /// @param variables undocumented.
574  /// @return XPathNode The first matching XPath node.
575  XPathNode FindSingleNode(const Char8* query, XPathVariableSet* variables = 0) const;
576 
577  /// @brief Select single node by evaluating an XPath query. Returns first node from the resulting node set.
578  /// @param query The XPath query XPathQuery class instance.
579  /// @return XPathNode The first matching XPath node.
580  XPathNode FindSingleNode(const XPathQuery& query) const;
581 
582  /// @brief Select a group of nodes by evaluating an XPath query.
583  /// @param query The XPath query as a c-string to be evaluated.
584  /// @param variables undocumented.
585  /// @return An XPathNodeSet with the Matchs of the XPath query.
586  XPathNodeSet FindNodes(const Char8* query, XPathVariableSet* variables = 0) const;
587 
588  /// @brief Select a group of nodes by evaluating an XPath query.
589  /// @param query The XPath query XPathQuery class instance.
590  /// @return An XPathNodeSet with the Matchs of the XPath query.
591  /// @param query The XPath query XPathQuery class instance.
592  XPathNodeSet FindNodes(const XPathQuery& query) const;
593 
594  #ifndef SWIG_SAFE
595  /// @brief Output the XML document using a Writer.
596  /// @param WriterInstance The Writer that will be used to output the xml text.
597  /// @param indent The Character(s) used to represent a tab in the output, this defaults to one tab character.
598  /// @param flags The output format flags, this is a bitfield that defaults to XML::FormatDefault.
599  /// @param DocumentEncoding The XML::Encoding of the document, whichs defaults to EncodingAuto
600  /// @param Depth This defaults to 0. The amount of times to prepend the indentation to the beginning of each output line.
601  /// @details This will never write a Byte Order Mark(BOM), and will default to not outputing a document declaration.
602  /// @note This is not available in the safe libraries in scripting languages
603  void Print(Writer& WriterInstance, const Char8* indent = "\t", unsigned int flags = FormatDefault, Encoding DocumentEncoding = EncodingAuto, unsigned int Depth = 0) const;
604 
605  /// @brief Output the XML document using a Output Stream.
606  /// @param os An output stream to send xml text to.
607  /// @param indent The Character(s) used to represent a tab in the outpput, this defaults to one tab character.
608  /// @param flags The output format flags, this is a bitfield that defaults to XML::FormatDefault
609  /// @param DocumentEncoding The XML::Encoding of the document, whichs defaults to EncodingAuto
610  /// @param Depth This defaults to 0. The amount of times to prepend the indentation to the beginning of each output line.
611  /// @details This will never write a Byte Order Mark(BOM), and will default to not outputing a document declaration.
612  /// @note This is not available in the safe libraries in scripting languages
613  void Print(std::basic_ostream<char, std::char_traits<char> >& os, const Char8* indent = "\t", unsigned int flags = FormatDefault, Encoding DocumentEncoding = EncodingAuto, unsigned int Depth = 0) const;
614 
615  /// @brief Output the XML document using a Output Stream.
616  /// @param os An output stream to send xml text to.
617  /// @param indent The Character(s) used to represent a tab in the outpput, this defaults to one tab character.
618  /// @param flags The output format flags, this is a bitfield that defaults to XML::FormatDefault
619  /// @param Depth This defaults to 0. The amount of times to prepend the indentation to the beginning of each output line.
620  /// @details This will never write a Byte Order Mark(BOM), and will default to not outputing a document declaration.
621  /// @note This is not available in the safe libraries in scripting languages
622  void Print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& os, const Char8* indent = "\t", unsigned int flags = FormatDefault, unsigned int Depth = 0) const;
623  #endif //SWIG_SAFE
624 
625  /// @brief An iterator for child Nodes that will be easier for members of the std namespace to work with.
627 
628  /// @brief Get a Child node iterator that references the first child Node.
629  /// @return A Node::Iterator that reference the first child Node.
630  iterator begin() const;
631 
632  /// @brief Get a Child node iterator that references one past the last child Node.
633  /// @return A Node::Iterator that reference the last child Node.
634  iterator end() const;
635 
636  /// @brief An iterator for Attribute members on this Node
638 
639  /// @brief Get an Attribute iterator that references the first Attribute on this Node.
640  /// @return A Node::Iterator that reference the first child node.
641  attribute_iterator attributes_begin() const;
642 
643  /// @brief Get an Attribute iterator that references the one past the last Attribute on this Node.
644  /// @return A Node::Iterator that reference the last Attribute on this Node.
645  attribute_iterator attributes_end() const;
646 
647  /// @brief Get an iterator range for this node's children nodes.
648  /// @return The Begin and end iterators for a collection of all child nodes.
649  ObjectRange<NodeIterator> GetChildren() const;
650 
651  /// @brief Get an iterator range for this a subset of this node's children nodes.
652  /// @param Name All members of the returned range with have this for a name.
653  /// @return A begin and end iterator for a range containing only the child nodes with the given name.
654  ObjectRange<NamedNodeIterator> GetChildren(const Char8* Name) const;
655 
656  /// @brief A range of iterators for just the attributes of this node.
657  /// @return A par of iterators suitable for traversing all Attributes directly as children of this noce.
658  ObjectRange<AttributeIterator> attributes() const;
659 
660  /// @internal
661  /// @brief Get node Offset in parsed file/string (in char_t units) for debugging purposes
662  /// @return A ptrdiff_t containing how far into the document this node is.
663  ptrdiff_t OffSetDebug() const;
664 
665  /// @internal
666  /// @brief Get hash Value (unique for handles to the same object)
667  /// @return A size_t that uniquely identifies this node.
668  size_t HashValue() const;
669 
670  /// @internal
671  /// @brief Get internal pointer
672  /// @return A NodeStruct* that points to the internal data of this Node
673  NodeStruct* InternalObject() const;
674  }; // /Class Node
675  }
676 } // /namespace Mezzanine
677 
678 
679 
680 #endif // Include guard
681 
682 /*
683  *
684  * Software, Files, Libraries and all other items referenced in this clause refers only
685  * to the contents of this file and associated documentation.
686  *
687  * Copyright © 2006-2012 Arseny Kapoulkine
688  *
689  * Permission is hereby granted, free of charge, to any person
690  * obtaining a copy of this software and associated documentation
691  * files (the "Software"), to deal in the Software without
692  * restriction, including without limitation the rights to use,
693  * copy, modify, merge, publish, distribute, sublicense, and/or sell
694  * copies of the Software, and to permit persons to whom the
695  * Software is furnished to do so, subject to the following
696  * conditions:
697  *
698  * The above copyright notice and this permission notice shall be
699  * included in all copies or substantial portions of the Software.
700  *
701  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
702  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
703  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
704  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
705  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
706  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
707  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
708  * OTHER DEALINGS IN THE SOFTWARE.
709  */
Node PrependChild(const String &Name)
Creates an element Node as a child of this Node, with the given name at the beginning of the children...
Definition: node.h:415
bool SetName(const String &rhs)
Set the name of this object.
Definition: node.h:274
NodeStruct * NodeData
Stores pointers to the Node data and some metadata.
Definition: node.h:98
A light-weight handle for manipulating attributes in DOM tree.
Definition: attribute.h:74
Attribute GetNextAttribute() const
Get the next attribute.
A fixed sized collection of nodes that an XPathQuery can work on.
Definition: xpathnodeset.h:72
An XPath node which can store handles to a XML::Node or an XML::Attribute.
Definition: xpathnode.h:76
Node GetParent() const
Attempt to retrieve the parent of this Node.
A compiled XPath query object.
Definition: xpathquery.h:91
Node GetFirstChild() const
Get the first child Node of this Node.
All the definitions for datatypes as well as some basic conversion functions are defined here...
Node GetChild(const String &Name) const
Attempt to get a child Node with a given name.
Definition: node.h:235
Node FindNode(Predicate pred) const
Search for any Node descended from this Node using a function to check each Node individually.
Definition: node.h:516
Node GetNextSibling() const
Attempt to retrieve the next sibling of this Node.
A set of XPath variables.
Used to call a function OnEachNode member of the subtree of nodes descended from a specific node...
Definition: treewalker.h:83
Node FindChild(Predicate pred) const
Search for an child ( only direct children ) Node using a function to check each Node individually...
Definition: node.h:498
char Char8
A datatype to represent one character.
Definition: datatypes.h:169
Contains the definition for the XML::Attribute class.
Encoding
These flags determine the encoding of input data for an XML document.
Auto-detect input DocumentEncoding using BOM or < /
Child node iterator (a bidirectional iterator over a collection of Node)
Definition: nodeiterator.h:77
Used by the xml system to pass around iterable ranges.
Definition: objectrange.h:72
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
ProcessDepth Depth
The current process depth as interpretted by Main.
Definition: mezztest.cpp:82
AttributeIterator attribute_iterator
An iterator for Attribute members on this Node.
Definition: node.h:637
Contains the implementation of the ObjectRange class template.
Child node iterator (a forward iterator over a collection of Node) only iterates over nodes with a gi...
Definition: nodeiterator.h:159
NodeType
The types of nodes that could be in the XML Tree.
Node AppendChild(const String &Name)
Creates an element Node as a child of this Node, with the given name.
Definition: node.h:399
Enumerations and constant values used primarily in the XML system but useful for interacting with it ...
Attribute iterator (a bidirectional iterator over a collection of Attribute).
NodeIterator iterator
An iterator for child Nodes that will be easier for members of the std namespace to work with...
Definition: node.h:626
const unsigned int FormatDefault
The default set of formatting flags. Only FormatRaw is enabled.
#define MEZZ_LIB
Some platforms require special decorations to denote what is exported/imported in a share library...
Attribute AppendAttribute(const String &Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
Definition: node.h:298
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
Element tag, i.e. ''.
Attribute FindAttribute(Predicate pred) const
Search for an Attribute using a function to check each Attribute individually.
Definition: node.h:480
A helper for working with text inside PCDATA nodes.
Definition: nodetext.h:73
Interface for node printing (see Node::Print)
Definition: writer.h:80
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159