Skip to content

Commit

Permalink
Documented FunctionalInterface for NodeVisitor
Browse files Browse the repository at this point in the history
  • Loading branch information
jhy committed Nov 11, 2023
1 parent f9f34df commit 32a0b19
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
25 changes: 19 additions & 6 deletions src/main/java/org/jsoup/select/NodeVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,26 @@
import org.jsoup.nodes.Node;

/**
* Node visitor interface. Provide an implementing class to {@link NodeTraversor} to iterate through nodes.
* <p>
* This interface provides two methods, {@code head} and {@code tail}. The head method is called when the node is first
* seen, and the tail method when all of the node's children have been visited. As an example, {@code head} can be used to
* emit a start tag for a node, and {@code tail} to create the end tag.
* </p>
Node visitor interface. Provide an implementing class to {@link NodeTraversor} or to {@link Node#traverse(NodeVisitor)}
to iterate through nodes.
<p>
This interface provides two methods, {@link #head} and {@link #tail}. The head method is called when the node is first
seen, and the tail method when all of the node's children have been visited. As an example, {@code head} can be used to
emit a start tag for a node, and {@code tail} to create the end tag. The {@code tail} method defaults to a no-op, so
the {@code head} method is the {@link FunctionalInterface}.
</p>
<p><b>Example:</b></p>
<pre><code>
doc.body().traverse((node, depth) -> {
switch (node) {
case Element el -> print(el.tag() + ": " + el.ownText());
case DataNode data -> print("Data: " + data.getWholeData());
default -> print(node.nodeName() + " at depth " + depth);
}
});
</code></pre>
*/
@FunctionalInterface
public interface NodeVisitor {
/**
Callback for when a node is first visited.
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/org/jsoup/select/TraversorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.jsoup.nodes.TextNode;
import org.junit.jupiter.api.Test;

import java.util.concurrent.atomic.AtomicInteger;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

Expand Down Expand Up @@ -193,4 +195,19 @@ else if (node instanceof TextNode && ((TextNode) node).text().equals("Three"))

assertEquals("<div><p id=\"2\">Two</p><p></p></div>", TextUtil.stripNewlines(doc.body().html()));
}

@Test void elementFunctionalTraverse() {
Document doc = Jsoup.parse("<div><p>1<p>2<p>3");
Element body = doc.body();

AtomicInteger seenCount = new AtomicInteger();
AtomicInteger deepest = new AtomicInteger();
body.traverse((node, depth) -> {
seenCount.incrementAndGet();
if (depth > deepest.get()) deepest.set(depth);
});

assertEquals(8, seenCount.get()); // body and contents
assertEquals(3, deepest.get());
}
}

0 comments on commit 32a0b19

Please sign in to comment.