1 #ifndef __TRAVERSAL_H__
2 #define __TRAVERSAL_H__
4 /**
5 * Phoebe DOM Implementation.
6 *
7 * This is a C++ approximation of the W3C DOM model, which follows
8 * fairly closely the specifications in the various .idl files, copies of
9 * which are provided for reference. Most important is this one:
10 *
11 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
12 *
13 * Authors:
14 * Bob Jamison
15 *
16 * Copyright (C) 2005-2008 Bob Jamison
17 *
18 * This library is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU Lesser General Public
20 * License as published by the Free Software Foundation; either
21 * version 2.1 of the License, or (at your option) any later version.
22 *
23 * This library is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * Lesser General Public License for more details.
27 *
28 * You should have received a copy of the GNU Lesser General Public
29 * License along with this library; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 *
32 * ==========================================================================
33 * NOTES
34 *
35 * This interface is described here:
36 * http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113
37 */
40 #include "dom.h"
43 namespace org
44 {
45 namespace w3c
46 {
47 namespace dom
48 {
49 namespace traversal
50 {
53 //Local aliases
54 typedef dom::Node Node;
60 /*#########################################################################
61 ## NodeFilter
62 #########################################################################*/
64 /**
65 * Filters are objects that know how to "filter out" nodes. If a NodeIterator or
66 * TreeWalker is given a NodeFilter, it applies the filter before it returns the
67 * next node. If the filter says to accept the node, the traversal logic returns
68 * it; otherwise, traversal looks for the next node and pretends that the node
69 * that was rejected was not there.
70 *
71 * The DOM does not provide any filters. NodeFilter is just an interface that
72 * users can implement to provide their own filters.
73 *
74 * NodeFilters do not need to know how to traverse from node to node, nor do they
75 * need to know anything about the data structure that is being traversed. This
76 * makes it very easy to write filters, since the only thing they have to know
77 * how to do is evaluate a single node. One filter may be used with a number of
78 * different kinds of traversals, encouraging code reuse.
79 *
80 * Note:
81 * The spec is slightly vague on this interface, for instance, setting the
82 * whatToShow value.
83 */
84 class NodeFilter
85 {
86 public:
88 /**
89 * The following constants are returned by the acceptNode() method
90 */
91 typedef enum
92 {
93 FILTER_ACCEPT = 1,
94 FILTER_REJECT = 2,
95 FILTER_SKIP = 3
96 } AcceptNodeType;
98 /**
99 * Test whether a specified node is visible in the logical view of a TreeWalker
100 * or NodeIterator. This function will be called by the implementation of
101 * TreeWalker and NodeIterator; it is not normally called directly from user
102 * code. (Though you could do so if you wanted to use the same filter to guide
103 * your own application logic.)
104 */
105 virtual short acceptNode(const NodePtr /*n*/)
106 {
107 return 0;
108 }
111 /**
112 * These are the available values for the whatToShow parameter used in
113 * TreeWalkers and NodeIterators. They are the same as the set of possible types
114 * for Node, and their values are derived by using a bit position corresponding
115 * to the value of nodeType for the equivalent node type. If a bit in whatToShow
116 * is set false, that will be taken as a request to skip over this type of node;
117 * the behavior in that case is similar to that of FILTER_SKIP.
118 *
119 * Note that if node types greater than 32 are ever introduced, they may not be
120 * individually testable via whatToShow. If that need should arise, it can be
121 * handled by selecting SHOW_ALL together with an appropriate NodeFilter.
122 */
123 typedef enum
124 {
125 SHOW_ALL = 0xFFFFFFFF,
126 SHOW_ELEMENT = 0x00000001,
127 SHOW_ATTRIBUTE = 0x00000002,
128 SHOW_TEXT = 0x00000004,
129 SHOW_CDATA_SECTION = 0x00000008,
130 SHOW_ENTITY_REFERENCE = 0x00000010,
131 SHOW_ENTITY = 0x00000020,
132 SHOW_PROCESSING_INSTRUCTION = 0x00000040,
133 SHOW_COMMENT = 0x00000080,
134 SHOW_DOCUMENT = 0x00000100,
135 SHOW_DOCUMENT_TYPE = 0x00000200,
136 SHOW_DOCUMENT_FRAGMENT = 0x00000400,
137 SHOW_NOTATION = 0x00000800
138 } WhatToShowType;
143 //##################
144 //# Non-API methods
145 //##################
147 /**
148 *
149 */
150 NodeFilter() : whatToShow(SHOW_ALL)
151 {}
153 /**
154 *
155 */
156 NodeFilter(int whatToShowArg) : whatToShow(whatToShowArg)
157 {}
160 /**
161 *
162 */
163 NodeFilter(const NodeFilter &other)
164 {
165 whatToShow = other.whatToShow;
166 }
168 /**
169 *
170 */
171 NodeFilter& operator=(const NodeFilter &other)
172 {
173 whatToShow = other.whatToShow;
174 return *this;
175 }
177 /**
178 *
179 */
180 virtual ~NodeFilter() {}
183 int whatToShow;
185 };
189 /*#########################################################################
190 ## NodeIterator
191 #########################################################################*/
193 /**
194 * Iterators are used to step through a set of nodes, e.g. the set of nodes in a
195 * NodeList, the document subtree governed by a particular Node, the results of a
196 * query, or any other set of nodes. The set of nodes to be iterated is
197 * determined by the implementation of the NodeIterator. DOM Level 2 specifies a
198 * single NodeIterator implementation for document-order traversal of a document
199 * subtree. Instances of these iterators are created by calling
200 * DocumentTraversal .createNodeIterator().
201 */
202 class NodeIterator
203 {
204 public:
206 /**
207 * The root node of the NodeIterator, as specified when it was created.
208 */
209 virtual NodePtr getRoot()
210 {
211 NodePtr ptr;
212 return ptr;
213 }
215 /**
216 * This attribute determines which node types are presented via the iterator. The
217 * available set of constants is defined in the NodeFilter interface. Nodes not
218 * accepted by whatToShow will be skipped, but their children may still be
219 * considered. Note that this skip takes precedence over the filter, if any.
220 */
221 virtual unsigned long getWhatToShow()
222 { return whatToShow; }
224 /**
225 * The NodeFilter used to screen nodes.
226 */
227 virtual NodeFilter getFilter()
228 { return filter; }
230 /**
231 * The value of this flag determines whether the children of entity reference
232 * nodes are visible to the iterator. If false, they and their descendants will
233 * be rejected. Note that this rejection takes precedence over whatToShow and the
234 * filter. Also note that this is currently the only situation where
235 * NodeIterators may reject a complete subtree rather than skipping individual
236 * nodes.
237 *
238 * To produce a view of the document that has entity references expanded and does
239 * not expose the entity reference node itself, use the whatToShow flags to hide
240 * the entity reference node and set expandEntityReferences to true when creating
241 * the iterator. To produce a view of the document that has entity reference
242 * nodes but no entity expansion, use the whatToShow flags to show the entity
243 * reference node and set expandEntityReferences to false.
244 */
245 virtual bool getExpandEntityReferences()
246 { return expandEntityReferences; }
248 /**
249 * Returns the next node in the set and advances the position of the iterator in
250 * the set. After a NodeIterator is created, the first call to nextNode() returns
251 * the first node in the set.
252 */
253 virtual NodePtr nextNode() throw(dom::DOMException)
254 {
255 NodePtr ptr;
256 return ptr;
257 }
259 /**
260 * Returns the previous node in the set and moves the position of the
261 * NodeIterator backwards in the set.
262 */
263 virtual NodePtr previousNode() throw(dom::DOMException)
264 {
265 NodePtr ptr;
266 return ptr;
267 }
269 /**
270 * Detaches the NodeIterator from the set which it iterated over, releasing any
271 * computational resources and placing the iterator in the INVALID state. After
272 * detach has been invoked, calls to nextNode or previousNode will raise the
273 * exception INVALID_STATE_ERR.
274 */
275 virtual void detach()
276 {
277 }
281 //##################
282 //# Non-API methods
283 //##################
285 /**
286 *
287 */
288 NodeIterator() {}
290 /**
291 *
292 */
293 NodeIterator(const NodeIterator &other)
294 {
295 whatToShow = other.whatToShow;
296 filter = other.filter;
297 expandEntityReferences = other.expandEntityReferences;
298 }
300 /**
301 *
302 */
303 virtual ~NodeIterator() {}
305 protected:
307 unsigned long whatToShow;
308 NodeFilter filter;
309 bool expandEntityReferences;
312 };
316 /*#########################################################################
317 ## TreeWalker
318 #########################################################################*/
320 /**
321 * TreeWalker objects are used to navigate a document tree or subtree using the
322 * view of the document defined by their whatToShow flags and filter (if any).
323 * Any function which performs navigation using a TreeWalker will automatically
324 * support any view defined by a TreeWalker.
325 *
326 * Omitting nodes from the logical view of a subtree can result in a structure
327 * that is substantially different from the same subtree in the complete,
328 * unfiltered document. Nodes that are siblings in the TreeWalker view may be
329 * children of different, widely separated nodes in the original view. For
330 * instance, consider a NodeFilter that skips all nodes except for Text nodes and
331 * the root node of a document. In the logical view that results, all text nodes
332 * will be siblings and appear as direct children of the root node, no matter how
333 * deeply nested the structure of the original document.
334 */
335 class TreeWalker
336 {
337 public:
340 /**
341 * The root node of the TreeWalker, as specified when it was created.
342 */
343 virtual NodePtr getRoot()
344 {
345 NodePtr ptr;
346 return ptr;
347 }
349 /**
350 * This attribute determines which node types are presented via the TreeWalker.
351 * The available set of constants is defined in the NodeFilter interface. Nodes
352 * not accepted by whatToShow will be skipped, but their children may still be
353 * considered. Note that this skip takes precedence over the filter, if any.
354 */
355 virtual unsigned long getWhatToShow()
356 { return whatToShow; }
358 /**
359 * The filter used to screen nodes.
360 */
361 virtual NodeFilter getFilter()
362 { return filter; }
364 /**
365 * The value of this flag determines whether the children of entity reference
366 * nodes are visible to the TreeWalker. If false, they and their descendants will
367 * be rejected. Note that this rejection takes precedence over whatToShow and the
368 * filter, if any. To produce a view of the document that has entity references
369 * expanded and does not expose the entity reference node itself, use the
370 * whatToShow flags to hide the entity reference node and set
371 * expandEntityReferences to true when creating the TreeWalker. To produce a view
372 * of the document that has entity reference nodes but no entity expansion, use
373 * the whatToShow flags to show the entity reference node and set
374 * expandEntityReferences to false.
375 */
376 virtual bool getExpandEntityReferences()
377 { return expandEntityReferences; }
379 /**
380 * The node at which the TreeWalker is currently positioned. Alterations to the
381 * DOM tree may cause the current node to no longer be accepted by the
382 * TreeWalker's associated filter. currentNode may also be explicitly set to any
383 * node, whether or not it is within the subtree specified by the root node or
384 * would be accepted by the filter and whatToShow flags. Further traversal occurs
385 * relative to currentNode even if it is not part of the current view, by
386 * applying the filters in the requested direction; if no traversal is possible,
387 * currentNode is not changed.
388 */
389 virtual NodePtr getCurrentNode()
390 { return currentNode; }
392 /**
393 * Sets the value above.
394 */
395 virtual void setCurrentNode(const NodePtr val) throw(dom::DOMException)
396 { currentNode = val; }
398 /**
399 * Moves to and returns the closest visible ancestor node of the current node. If
400 * the search for parentNode attempts to step upward from the TreeWalker's root
401 * node, or if it fails to find a visible ancestor node, this method retains the
402 * current position and returns null.
403 */
404 virtual NodePtr parentNode()
405 {
406 NodePtr ptr;
407 return ptr;
408 }
410 /**
411 * Moves the TreeWalker to the first visible child of the current node, and
412 * returns the new node. If the current node has no visible children, returns
413 * null, and retains the current node.
414 */
415 virtual NodePtr firstChild()
416 {
417 NodePtr ptr;
418 return ptr;
419 }
421 /**
422 * Moves the TreeWalker to the last visible child of the current node, and
423 * returns the new node. If the current node has no visible children, returns
424 * null, and retains the current node.
425 */
426 virtual NodePtr lastChild()
427 {
428 NodePtr ptr;
429 return ptr;
430 }
432 /**
433 * Moves the TreeWalker to the previous sibling of the current node, and returns
434 * the new node. If the current node has no visible previous sibling, returns
435 * null, and retains the current node.
436 */
437 virtual NodePtr previousSibling()
438 {
439 NodePtr ptr;
440 return ptr;
441 }
443 /**
444 * Moves the TreeWalker to the next sibling of the current node, and returns the
445 * new node. If the current node has no visible next sibling, returns null, and
446 * retains the current node.
447 */
448 virtual NodePtr nextSibling()
449 {
450 NodePtr ptr;
451 return ptr;
452 }
454 /**
455 * Moves the TreeWalker to the previous visible node in document order relative
456 * to the current node, and returns the new node. If the current node has no
457 * previous node, or if the search for previousNode attempts to step upward from
458 * the TreeWalker's root node, returns null, and retains the current node.
459 */
460 virtual NodePtr previousNode()
461 {
462 NodePtr ptr;
463 return ptr;
464 }
466 /**
467 * Moves the TreeWalker to the next visible node in document order relative to
468 * the current node, and returns the new node. If the current node has no next
469 * node, or if the search for nextNode attempts to step upward from the
470 * TreeWalker's root node, returns null, and retains the current node.
471 */
472 virtual NodePtr nextNode()
473 {
474 NodePtr ptr;
475 return ptr;
476 }
480 //##################
481 //# Non-API methods
482 //##################
484 /**
485 *
486 */
487 TreeWalker() {}
489 /**
490 *
491 */
492 TreeWalker(const TreeWalker &other)
493 {
494 whatToShow = other.whatToShow;
495 filter = other.filter;
496 expandEntityReferences = other.expandEntityReferences;
497 currentNode = other.currentNode;
498 }
500 /**
501 *
502 */
503 virtual ~TreeWalker() {}
506 protected:
508 unsigned long whatToShow;
509 NodeFilter filter;
510 bool expandEntityReferences;
511 NodePtr currentNode;
513 };
518 /*#########################################################################
519 ## DocumentTraversal
520 #########################################################################*/
522 /**
523 * DocumentTraversal contains methods that create iterators and tree-walkers to
524 * traverse a node and its children in document order (depth first, pre-order
525 * traversal, which is equivalent to the order in which the start tags occur in
526 * the text representation of the document). In DOMs which support the Traversal
527 * feature, DocumentTraversal will be implemented by the same objects that
528 * implement the Document interface.
529 */
530 class DocumentTraversal
531 {
532 public:
534 /**
535 * Create a new NodeIterator over the subtree rooted at the specified node.
536 */
537 virtual NodeIterator createNodeIterator(const NodePtr /*root*/,
538 unsigned long /*whatToShow*/,
539 const NodeFilter/*filter*/,
540 bool /*entityReferenceExpansion*/)
541 throw (dom::DOMException)
542 {
543 NodeIterator ret;
544 return ret;
545 }
547 /**
548 * Create a new TreeWalker over the subtree rooted at the specified node.
549 */
550 virtual TreeWalker createTreeWalker(const NodePtr/*root*/,
551 unsigned long /*whatToShow*/,
552 const NodeFilter/*filter*/,
553 bool /*entityReferenceExpansion*/)
554 throw (dom::DOMException)
555 {
556 TreeWalker ret;
557 return ret;
558 }
561 //##################
562 //# Non-API methods
563 //##################
565 /**
566 *
567 */
568 DocumentTraversal() {}
570 /**
571 *
572 */
573 DocumentTraversal(const DocumentTraversal &/*other*/)
574 {}
576 /**
577 *
578 */
579 virtual ~DocumentTraversal() {}
581 };
588 } //namespace traversal
589 } //namespace dom
590 } //namespace w3c
591 } //namespace org
593 #endif /* __TRAVERSAL_H__ */
596 /*#########################################################################
597 ## E N D O F F I L E
598 #########################################################################*/