aboutsummaryrefslogtreecommitdiffstats
path: root/server/src/org/jsoup/select/NodeTraversor.java
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/org/jsoup/select/NodeTraversor.java')
-rw-r--r--server/src/org/jsoup/select/NodeTraversor.java47
1 files changed, 47 insertions, 0 deletions
diff --git a/server/src/org/jsoup/select/NodeTraversor.java b/server/src/org/jsoup/select/NodeTraversor.java
new file mode 100644
index 0000000000..9bb081e56c
--- /dev/null
+++ b/server/src/org/jsoup/select/NodeTraversor.java
@@ -0,0 +1,47 @@
+package org.jsoup.select;
+
+import org.jsoup.nodes.Node;
+
+/**
+ * Depth-first node traversor. Use to iterate through all nodes under and including the specified root node.
+ * <p/>
+ * This implementation does not use recursion, so a deep DOM does not risk blowing the stack.
+ */
+public class NodeTraversor {
+ private NodeVisitor visitor;
+
+ /**
+ * Create a new traversor.
+ * @param visitor a class implementing the {@link NodeVisitor} interface, to be called when visiting each node.
+ */
+ public NodeTraversor(NodeVisitor visitor) {
+ this.visitor = visitor;
+ }
+
+ /**
+ * Start a depth-first traverse of the root and all of its descendants.
+ * @param root the root node point to traverse.
+ */
+ public void traverse(Node root) {
+ Node node = root;
+ int depth = 0;
+
+ while (node != null) {
+ visitor.head(node, depth);
+ if (node.childNodes().size() > 0) {
+ node = node.childNode(0);
+ depth++;
+ } else {
+ while (node.nextSibling() == null && depth > 0) {
+ visitor.tail(node, depth);
+ node = node.parent();
+ depth--;
+ }
+ visitor.tail(node, depth);
+ if (node == root)
+ break;
+ node = node.nextSibling();
+ }
+ }
+ }
+}