public class CommentRangeEnd
To create a comment anchored to a region of text, you need to create a
Example:
Shows how print the contents of all comments and their comment ranges using a document visitor.Document doc = new Document(); Comment newComment = new Comment(doc); { newComment.setAuthor("VDeryushev"); newComment.setInitial("VD"); newComment.setDateTime(new Date()); } newComment.setText("Comment regarding text."); // Add text to the document, warp it in a comment range, and then add your comment. Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); para.appendChild(new CommentRangeStart(doc, newComment.getId())); para.appendChild(new Run(doc, "Commented text.")); para.appendChild(new CommentRangeEnd(doc, newComment.getId())); para.appendChild(newComment); // Add two replies to the comment. newComment.addReply("John Doe", "JD", new Date(), "New reply."); newComment.addReply("John Doe", "JD", new Date(), "Another reply."); printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true)); } /// <summary> /// Iterates over every top-level comment and prints its comment range, contents, and replies. /// </summary> private static void printAllCommentInfo(NodeCollection comments) throws Exception { CommentInfoPrinter commentVisitor = new CommentInfoPrinter(); // Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor. for (Comment comment : (Iterable<Comment>) comments) { if (comment.getAncestor() == null) { // First, visit the start of the comment range. CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling(); commentRangeStart.accept(commentVisitor); // Then, visit the comment, and any replies that it may have. comment.accept(commentVisitor); for (Comment reply : comment.getReplies()) reply.accept(commentVisitor); // Finally, visit the end of the comment range, and then print the visitor's text contents. CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling(); commentRangeEnd.accept(commentVisitor); System.out.println(commentVisitor.getText()); } } } /// <summary> /// Prints information and contents of all comments and comment ranges encountered in the document. /// </summary> public static class CommentInfoPrinter extends DocumentVisitor { public CommentInfoPrinter() { mBuilder = new StringBuilder(); mVisitorIsInsideComment = false; } /// <summary> /// Gets the plain text of the document that was accumulated by the visitor. /// </summary> public String getText() { return mBuilder.toString(); } /// <summary> /// Called when a Run node is encountered in the document. /// </summary> public int visitRun(Run run) { if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\""); return VisitorAction.CONTINUE; } /// <summary> /// Called when a CommentRangeStart node is encountered in the document. /// </summary> public int visitCommentRangeStart(CommentRangeStart commentRangeStart) { indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId()); mDocTraversalDepth++; mVisitorIsInsideComment = true; return VisitorAction.CONTINUE; } /// <summary> /// Called when a CommentRangeEnd node is encountered in the document. /// </summary> public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) { mDocTraversalDepth--; indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n"); mVisitorIsInsideComment = false; return VisitorAction.CONTINUE; } /// <summary> /// Called when a Comment node is encountered in the document. /// </summary> public int visitCommentStart(Comment comment) { indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(), comment.getAuthor(), comment.getDateTime())); mDocTraversalDepth++; mVisitorIsInsideComment = true; return VisitorAction.CONTINUE; } /// <summary> /// Called when the visiting of a Comment node is ended in the document. /// </summary> public int visitCommentEnd(Comment comment) { mDocTraversalDepth--; indentAndAppendLine("[Comment end]"); mVisitorIsInsideComment = false; return VisitorAction.CONTINUE; } /// <summary> /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. /// </summary> /// <param name="text"></param> private void indentAndAppendLine(String text) { for (int i = 0; i < mDocTraversalDepth; i++) { mBuilder.append("| "); } mBuilder.append(text + "\r\n"); } private boolean mVisitorIsInsideComment; private int mDocTraversalDepth; private final StringBuilder mBuilder; }
Constructor Summary |
---|
CommentRangeEnd(DocumentBase doc, intid)
Initializes a new instance of this class. |
Property Getters/Setters Summary | ||
---|---|---|
int | getCustomNodeId() | |
void | setCustomNodeId(intvalue) | |
Specifies custom node identifier. | ||
DocumentBase | getDocument() | |
Gets the document to which this node belongs.
|
||
int | getId() | |
void | setId(intvalue) | |
Specifies the identifier of the comment to which this region is linked to. | ||
boolean | isComposite() | |
Returns true if this node can contain other nodes.
|
||
Node | getNextSibling() | |
Gets the node immediately following this node.
|
||
int | getNodeType() | |
Returns |
||
CompositeNode | getParentNode() | |
Gets the immediate parent of this node.
|
||
Node | getPreviousSibling() | |
Gets the node immediately preceding this node.
|
||
Range | getRange() | |
Returns a Range object that represents the portion of a document that is contained in this node.
|
Method Summary | ||
---|---|---|
boolean | accept(DocumentVisitor visitor) | |
Accepts a visitor.
|
||
Node | deepClone(boolean isCloneChildren) | |
Creates a duplicate of the node.
|
||
CompositeNode | getAncestor(int ancestorType) | |
Gets the first ancestor of the specified |
||
CompositeNode | getAncestor(java.lang.Class ancestorType) | |
Gets the first ancestor of the specified object type.
|
||
java.lang.String | getText() | |
Gets the text of this node and of all its children.
|
||
Node | nextPreOrder(Node rootNode) | |
Gets next node according to the pre-order tree traversal algorithm.
|
||
Node | previousPreOrder(Node rootNode) | |
Gets the previous node according to the pre-order tree traversal algorithm.
|
||
void | remove() | |
Removes itself from the parent.
|
||
java.lang.String | toString(SaveOptions saveOptions) | |
Exports the content of the node into a string using the specified save options.
|
||
java.lang.String | toString(int saveFormat) | |
Exports the content of the node into a string in the specified format.
|
public CommentRangeEnd(DocumentBase doc, int id)
When
To append a
doc
- The owner document.id
- The comment identifier to which this object is linked.Example:
Shows how print the contents of all comments and their comment ranges using a document visitor.Document doc = new Document(); Comment newComment = new Comment(doc); { newComment.setAuthor("VDeryushev"); newComment.setInitial("VD"); newComment.setDateTime(new Date()); } newComment.setText("Comment regarding text."); // Add text to the document, warp it in a comment range, and then add your comment. Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); para.appendChild(new CommentRangeStart(doc, newComment.getId())); para.appendChild(new Run(doc, "Commented text.")); para.appendChild(new CommentRangeEnd(doc, newComment.getId())); para.appendChild(newComment); // Add two replies to the comment. newComment.addReply("John Doe", "JD", new Date(), "New reply."); newComment.addReply("John Doe", "JD", new Date(), "Another reply."); printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true)); } /// <summary> /// Iterates over every top-level comment and prints its comment range, contents, and replies. /// </summary> private static void printAllCommentInfo(NodeCollection comments) throws Exception { CommentInfoPrinter commentVisitor = new CommentInfoPrinter(); // Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor. for (Comment comment : (Iterable<Comment>) comments) { if (comment.getAncestor() == null) { // First, visit the start of the comment range. CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling(); commentRangeStart.accept(commentVisitor); // Then, visit the comment, and any replies that it may have. comment.accept(commentVisitor); for (Comment reply : comment.getReplies()) reply.accept(commentVisitor); // Finally, visit the end of the comment range, and then print the visitor's text contents. CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling(); commentRangeEnd.accept(commentVisitor); System.out.println(commentVisitor.getText()); } } } /// <summary> /// Prints information and contents of all comments and comment ranges encountered in the document. /// </summary> public static class CommentInfoPrinter extends DocumentVisitor { public CommentInfoPrinter() { mBuilder = new StringBuilder(); mVisitorIsInsideComment = false; } /// <summary> /// Gets the plain text of the document that was accumulated by the visitor. /// </summary> public String getText() { return mBuilder.toString(); } /// <summary> /// Called when a Run node is encountered in the document. /// </summary> public int visitRun(Run run) { if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\""); return VisitorAction.CONTINUE; } /// <summary> /// Called when a CommentRangeStart node is encountered in the document. /// </summary> public int visitCommentRangeStart(CommentRangeStart commentRangeStart) { indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId()); mDocTraversalDepth++; mVisitorIsInsideComment = true; return VisitorAction.CONTINUE; } /// <summary> /// Called when a CommentRangeEnd node is encountered in the document. /// </summary> public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) { mDocTraversalDepth--; indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n"); mVisitorIsInsideComment = false; return VisitorAction.CONTINUE; } /// <summary> /// Called when a Comment node is encountered in the document. /// </summary> public int visitCommentStart(Comment comment) { indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(), comment.getAuthor(), comment.getDateTime())); mDocTraversalDepth++; mVisitorIsInsideComment = true; return VisitorAction.CONTINUE; } /// <summary> /// Called when the visiting of a Comment node is ended in the document. /// </summary> public int visitCommentEnd(Comment comment) { mDocTraversalDepth--; indentAndAppendLine("[Comment end]"); mVisitorIsInsideComment = false; return VisitorAction.CONTINUE; } /// <summary> /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. /// </summary> /// <param name="text"></param> private void indentAndAppendLine(String text) { for (int i = 0; i < mDocTraversalDepth; i++) { mBuilder.append("| "); } mBuilder.append(text + "\r\n"); } private boolean mVisitorIsInsideComment; private int mDocTraversalDepth; private final StringBuilder mBuilder; }
public int getCustomNodeId() / public void setCustomNodeId(int value)
Default is zero.
This identifier can be set and used arbitrarily. For example, as a key to get external data.
Important note, specified value is not saved to an output file and exists only during the node lifetime.
Example:
Shows how to traverse through a composite node's collection of child nodes.Document doc = new Document(); // Add two runs and one shape as child nodes to the first paragraph of this document. Paragraph paragraph = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); paragraph.appendChild(new Run(doc, "Hello world! ")); Shape shape = new Shape(doc, ShapeType.RECTANGLE); shape.setWidth(200.0); shape.setHeight(200.0); // Note that the 'CustomNodeId' is not saved to an output file and exists only during the node lifetime. shape.setCustomNodeId(100); shape.setWrapType(WrapType.INLINE); paragraph.appendChild(shape); paragraph.appendChild(new Run(doc, "Hello again!")); // Iterate through the paragraph's collection of immediate children, // and print any runs or shapes that we find within. NodeCollection children = paragraph.getChildNodes(); Assert.assertEquals(3, paragraph.getChildNodes().getCount()); for (Node child : (Iterable<Node>) children) switch (child.getNodeType()) { case NodeType.RUN: System.out.println("Run contents:"); System.out.println("\t\"{child.GetText().Trim()}\""); break; case NodeType.SHAPE: Shape childShape = (Shape) child; System.out.println("Shape:"); System.out.println("\t{childShape.ShapeType}, {childShape.Width}x{childShape.Height}"); }
public DocumentBase getDocument()
The node always belongs to a document even if it has just been created and not yet added to the tree, or if it has been removed from the tree.
Example:
Shows how to create a node and set its owning document.Document doc = new Document(); Paragraph para = new Paragraph(doc); para.appendChild(new Run(doc, "Hello world!")); // We have not yet appended this paragraph as a child to any composite node. Assert.assertNull(para.getParentNode()); // If a node is an appropriate child node type of another composite node, // we can attach it as a child only if both nodes have the same owner document. // The owner document is the document we passed to the node's constructor. // We have not attached this paragraph to the document, so the document does not contain its text. Assert.assertEquals(para.getDocument(), doc); Assert.assertEquals("", doc.getText().trim()); // Since the document owns this paragraph, we can apply one of its styles to the paragraph's contents. para.getParagraphFormat().setStyleName("Heading 1"); // Add this node to the document, and then verify its contents. doc.getFirstSection().getBody().appendChild(para); Assert.assertEquals(doc.getFirstSection().getBody(), para.getParentNode()); Assert.assertEquals("Hello world!", doc.getText().trim());
public int getId() / public void setId(int value)
Example:
Shows how print the contents of all comments and their comment ranges using a document visitor.Document doc = new Document(); Comment newComment = new Comment(doc); { newComment.setAuthor("VDeryushev"); newComment.setInitial("VD"); newComment.setDateTime(new Date()); } newComment.setText("Comment regarding text."); // Add text to the document, warp it in a comment range, and then add your comment. Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); para.appendChild(new CommentRangeStart(doc, newComment.getId())); para.appendChild(new Run(doc, "Commented text.")); para.appendChild(new CommentRangeEnd(doc, newComment.getId())); para.appendChild(newComment); // Add two replies to the comment. newComment.addReply("John Doe", "JD", new Date(), "New reply."); newComment.addReply("John Doe", "JD", new Date(), "Another reply."); printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true)); } /// <summary> /// Iterates over every top-level comment and prints its comment range, contents, and replies. /// </summary> private static void printAllCommentInfo(NodeCollection comments) throws Exception { CommentInfoPrinter commentVisitor = new CommentInfoPrinter(); // Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor. for (Comment comment : (Iterable<Comment>) comments) { if (comment.getAncestor() == null) { // First, visit the start of the comment range. CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling(); commentRangeStart.accept(commentVisitor); // Then, visit the comment, and any replies that it may have. comment.accept(commentVisitor); for (Comment reply : comment.getReplies()) reply.accept(commentVisitor); // Finally, visit the end of the comment range, and then print the visitor's text contents. CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling(); commentRangeEnd.accept(commentVisitor); System.out.println(commentVisitor.getText()); } } } /// <summary> /// Prints information and contents of all comments and comment ranges encountered in the document. /// </summary> public static class CommentInfoPrinter extends DocumentVisitor { public CommentInfoPrinter() { mBuilder = new StringBuilder(); mVisitorIsInsideComment = false; } /// <summary> /// Gets the plain text of the document that was accumulated by the visitor. /// </summary> public String getText() { return mBuilder.toString(); } /// <summary> /// Called when a Run node is encountered in the document. /// </summary> public int visitRun(Run run) { if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\""); return VisitorAction.CONTINUE; } /// <summary> /// Called when a CommentRangeStart node is encountered in the document. /// </summary> public int visitCommentRangeStart(CommentRangeStart commentRangeStart) { indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId()); mDocTraversalDepth++; mVisitorIsInsideComment = true; return VisitorAction.CONTINUE; } /// <summary> /// Called when a CommentRangeEnd node is encountered in the document. /// </summary> public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) { mDocTraversalDepth--; indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n"); mVisitorIsInsideComment = false; return VisitorAction.CONTINUE; } /// <summary> /// Called when a Comment node is encountered in the document. /// </summary> public int visitCommentStart(Comment comment) { indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(), comment.getAuthor(), comment.getDateTime())); mDocTraversalDepth++; mVisitorIsInsideComment = true; return VisitorAction.CONTINUE; } /// <summary> /// Called when the visiting of a Comment node is ended in the document. /// </summary> public int visitCommentEnd(Comment comment) { mDocTraversalDepth--; indentAndAppendLine("[Comment end]"); mVisitorIsInsideComment = false; return VisitorAction.CONTINUE; } /// <summary> /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. /// </summary> /// <param name="text"></param> private void indentAndAppendLine(String text) { for (int i = 0; i < mDocTraversalDepth; i++) { mBuilder.append("| "); } mBuilder.append(text + "\r\n"); } private boolean mVisitorIsInsideComment; private int mDocTraversalDepth; private final StringBuilder mBuilder; }
public boolean isComposite()
Example:
Shows how to traverse a composite node's tree of child nodes.Document doc = new Document(getMyDir() + "Paragraphs.docx"); // Any node that can contain child nodes, such as the document itself, is composite. Assert.assertTrue(doc.isComposite()); // Invoke the recursive function that will go through and print all the child nodes of a composite node. traverseAllNodes(doc, 0); } /// <summary> /// Recursively traverses a node tree while printing the type of each node /// with an indent depending on depth as well as the contents of all inline nodes. /// </summary> @Test(enabled = false) public void traverseAllNodes(CompositeNode parentNode, int depth) { for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { System.out.println(MessageFormat.format("{0}{1}", String.format(" ", depth), Node.nodeTypeToString(childNode.getNodeType()))); // Recurse into the node if it is a composite node. Otherwise, print its contents if it is an inline node. if (childNode.isComposite()) { System.out.println(); traverseAllNodes((CompositeNode) childNode, depth + 1); } else if (childNode instanceof Inline) { System.out.println(" - \"{childNode.GetText().Trim()}\""); } else { System.out.println(); } } }
public Node getNextSibling()
Example:
Shows how to use a node's NextSibling property to enumerate through its immediate children.Document doc = new Document(getMyDir() + "Paragraphs.docx"); for (Node node = doc.getFirstSection().getBody().getFirstChild(); node != null; node = node.getNextSibling()) { System.out.println(Node.nodeTypeToString(node.getNodeType())); }
Example:
Shows how to traverse a composite node's tree of child nodes.Document doc = new Document(getMyDir() + "Paragraphs.docx"); // Any node that can contain child nodes, such as the document itself, is composite. Assert.assertTrue(doc.isComposite()); // Invoke the recursive function that will go through and print all the child nodes of a composite node. traverseAllNodes(doc, 0); } /// <summary> /// Recursively traverses a node tree while printing the type of each node /// with an indent depending on depth as well as the contents of all inline nodes. /// </summary> @Test(enabled = false) public void traverseAllNodes(CompositeNode parentNode, int depth) { for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { System.out.println(MessageFormat.format("{0}{1}", String.format(" ", depth), Node.nodeTypeToString(childNode.getNodeType()))); // Recurse into the node if it is a composite node. Otherwise, print its contents if it is an inline node. if (childNode.isComposite()) { System.out.println(); traverseAllNodes((CompositeNode) childNode, depth + 1); } else if (childNode instanceof Inline) { System.out.println(" - \"{childNode.GetText().Trim()}\""); } else { System.out.println(); } } }
public int getNodeType()
Example:
Shows how to traverse a composite node's tree of child nodes.Document doc = new Document(getMyDir() + "Paragraphs.docx"); // Any node that can contain child nodes, such as the document itself, is composite. Assert.assertTrue(doc.isComposite()); // Invoke the recursive function that will go through and print all the child nodes of a composite node. traverseAllNodes(doc, 0); } /// <summary> /// Recursively traverses a node tree while printing the type of each node /// with an indent depending on depth as well as the contents of all inline nodes. /// </summary> @Test(enabled = false) public void traverseAllNodes(CompositeNode parentNode, int depth) { for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { System.out.println(MessageFormat.format("{0}{1}", String.format(" ", depth), Node.nodeTypeToString(childNode.getNodeType()))); // Recurse into the node if it is a composite node. Otherwise, print its contents if it is an inline node. if (childNode.isComposite()) { System.out.println(); traverseAllNodes((CompositeNode) childNode, depth + 1); } else if (childNode instanceof Inline) { System.out.println(" - \"{childNode.GetText().Trim()}\""); } else { System.out.println(); } } }
public CompositeNode getParentNode()
If a node has just been created and not yet added to the tree, or if it has been removed from the tree, the parent is null.
Example:
Shows how to access a node's parent node.Document doc = new Document(); Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); // Append a child Run node to the document's first paragraph. Run run = new Run(doc, "Hello world!"); para.appendChild(run); // The paragraph is the parent node of the run node. We can trace this lineage // all the way to the document node, which is the root of the document's node tree. Assert.assertEquals(para, run.getParentNode()); Assert.assertEquals(doc.getFirstSection().getBody(), para.getParentNode()); Assert.assertEquals(doc.getFirstSection(), doc.getFirstSection().getBody().getParentNode()); Assert.assertEquals(doc, doc.getFirstSection().getParentNode());
Example:
Shows how to create a node and set its owning document.Document doc = new Document(); Paragraph para = new Paragraph(doc); para.appendChild(new Run(doc, "Hello world!")); // We have not yet appended this paragraph as a child to any composite node. Assert.assertNull(para.getParentNode()); // If a node is an appropriate child node type of another composite node, // we can attach it as a child only if both nodes have the same owner document. // The owner document is the document we passed to the node's constructor. // We have not attached this paragraph to the document, so the document does not contain its text. Assert.assertEquals(para.getDocument(), doc); Assert.assertEquals("", doc.getText().trim()); // Since the document owns this paragraph, we can apply one of its styles to the paragraph's contents. para.getParagraphFormat().setStyleName("Heading 1"); // Add this node to the document, and then verify its contents. doc.getFirstSection().getBody().appendChild(para); Assert.assertEquals(doc.getFirstSection().getBody(), para.getParentNode()); Assert.assertEquals("Hello world!", doc.getText().trim());
public Node getPreviousSibling()
Example:
Shows how to use of methods of Node and CompositeNode to remove a section before the last section in the document.Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); builder.writeln("Section 1 text."); builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); builder.writeln("Section 2 text."); // Both sections are siblings of each other. Section lastSection = (Section) doc.getLastChild(); Section firstSection = (Section) lastSection.getPreviousSibling(); // Remove a section based on its sibling relationship with another section. if (lastSection.getPreviousSibling() != null) doc.removeChild(firstSection); // The section we removed was the first one, leaving the document with only the second. Assert.assertEquals("Section 2 text.", doc.getText().trim());
public Range getRange()
Example:
Shows how to delete all the nodes from a range.Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); // Add text to the first section in the document, and then add another section. builder.write("Section 1. "); builder.insertBreak(BreakType.SECTION_BREAK_CONTINUOUS); builder.write("Section 2."); Assert.assertEquals("Section 1. \fSection 2.", doc.getText().trim()); // Remove the first section entirely by removing all the nodes // within its range, including the section itself. doc.getSections().get(0).getRange().delete(); Assert.assertEquals(1, doc.getSections().getCount()); Assert.assertEquals("Section 2.", doc.getText().trim());
public boolean accept(DocumentVisitor visitor) throws java.lang.Exception
Calls
For more info see the Visitor design pattern.
visitor
- The visitor that will visit the node.Example:
Shows how print the contents of all comments and their comment ranges using a document visitor.Document doc = new Document(); Comment newComment = new Comment(doc); { newComment.setAuthor("VDeryushev"); newComment.setInitial("VD"); newComment.setDateTime(new Date()); } newComment.setText("Comment regarding text."); // Add text to the document, warp it in a comment range, and then add your comment. Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); para.appendChild(new CommentRangeStart(doc, newComment.getId())); para.appendChild(new Run(doc, "Commented text.")); para.appendChild(new CommentRangeEnd(doc, newComment.getId())); para.appendChild(newComment); // Add two replies to the comment. newComment.addReply("John Doe", "JD", new Date(), "New reply."); newComment.addReply("John Doe", "JD", new Date(), "Another reply."); printAllCommentInfo(doc.getChildNodes(NodeType.COMMENT, true)); } /// <summary> /// Iterates over every top-level comment and prints its comment range, contents, and replies. /// </summary> private static void printAllCommentInfo(NodeCollection comments) throws Exception { CommentInfoPrinter commentVisitor = new CommentInfoPrinter(); // Iterate over all top-level comments. Unlike reply-type comments, top-level comments have no ancestor. for (Comment comment : (Iterable<Comment>) comments) { if (comment.getAncestor() == null) { // First, visit the start of the comment range. CommentRangeStart commentRangeStart = (CommentRangeStart) comment.getPreviousSibling().getPreviousSibling().getPreviousSibling(); commentRangeStart.accept(commentVisitor); // Then, visit the comment, and any replies that it may have. comment.accept(commentVisitor); for (Comment reply : comment.getReplies()) reply.accept(commentVisitor); // Finally, visit the end of the comment range, and then print the visitor's text contents. CommentRangeEnd commentRangeEnd = (CommentRangeEnd) comment.getPreviousSibling(); commentRangeEnd.accept(commentVisitor); System.out.println(commentVisitor.getText()); } } } /// <summary> /// Prints information and contents of all comments and comment ranges encountered in the document. /// </summary> public static class CommentInfoPrinter extends DocumentVisitor { public CommentInfoPrinter() { mBuilder = new StringBuilder(); mVisitorIsInsideComment = false; } /// <summary> /// Gets the plain text of the document that was accumulated by the visitor. /// </summary> public String getText() { return mBuilder.toString(); } /// <summary> /// Called when a Run node is encountered in the document. /// </summary> public int visitRun(Run run) { if (mVisitorIsInsideComment) indentAndAppendLine("[Run] \"" + run.getText() + "\""); return VisitorAction.CONTINUE; } /// <summary> /// Called when a CommentRangeStart node is encountered in the document. /// </summary> public int visitCommentRangeStart(CommentRangeStart commentRangeStart) { indentAndAppendLine("[Comment range start] ID: " + commentRangeStart.getId()); mDocTraversalDepth++; mVisitorIsInsideComment = true; return VisitorAction.CONTINUE; } /// <summary> /// Called when a CommentRangeEnd node is encountered in the document. /// </summary> public int visitCommentRangeEnd(CommentRangeEnd commentRangeEnd) { mDocTraversalDepth--; indentAndAppendLine("[Comment range end] ID: " + commentRangeEnd.getId() + "\n"); mVisitorIsInsideComment = false; return VisitorAction.CONTINUE; } /// <summary> /// Called when a Comment node is encountered in the document. /// </summary> public int visitCommentStart(Comment comment) { indentAndAppendLine(MessageFormat.format("[Comment start] For comment range ID {0}, By {1} on {2}", comment.getId(), comment.getAuthor(), comment.getDateTime())); mDocTraversalDepth++; mVisitorIsInsideComment = true; return VisitorAction.CONTINUE; } /// <summary> /// Called when the visiting of a Comment node is ended in the document. /// </summary> public int visitCommentEnd(Comment comment) { mDocTraversalDepth--; indentAndAppendLine("[Comment end]"); mVisitorIsInsideComment = false; return VisitorAction.CONTINUE; } /// <summary> /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. /// </summary> /// <param name="text"></param> private void indentAndAppendLine(String text) { for (int i = 0; i < mDocTraversalDepth; i++) { mBuilder.append("| "); } mBuilder.append(text + "\r\n"); } private boolean mVisitorIsInsideComment; private int mDocTraversalDepth; private final StringBuilder mBuilder; }
public Node deepClone(boolean isCloneChildren)
This method serves as a copy constructor for nodes. The cloned node has no parent, but belongs to the same document as the original node.
This method always performs a deep copy of the node. The isCloneChildren parameter specifies whether to perform copy all child nodes as well.
isCloneChildren
- True to recursively clone the subtree under the specified node;
false to clone only the node itself.Example:
Shows how to clone a composite node.Document doc = new Document(); Paragraph para = doc.getFirstSection().getBody().getFirstParagraph(); para.appendChild(new Run(doc, "Hello world!")); // Below are two ways of cloning a composite node. // 1 - Create a clone of a node, and create a clone of each of its child nodes as well. Node cloneWithChildren = para.deepClone(true); Assert.assertTrue(((CompositeNode) cloneWithChildren).hasChildNodes()); Assert.assertEquals("Hello world!", cloneWithChildren.getText().trim()); // 2 - Create a clone of a node just by itself without any children. Node cloneWithoutChildren = para.deepClone(false); Assert.assertFalse(((CompositeNode) cloneWithoutChildren).hasChildNodes()); Assert.assertEquals("", cloneWithoutChildren.getText().trim());
public CompositeNode getAncestor(int ancestorType)
ancestorType
- A Example:
Shows how to find out if a tables are nested.Document doc = new Document(getMyDir() + "Nested tables.docx"); NodeCollection tables = doc.getChildNodes(NodeType.TABLE, true); for (int i = 0; i < tables.getCount(); i++) { Table table = (Table) tables.get(i); // Find out if any cells in the table have other tables as children. int count = getChildTableCount(table); System.out.print(MessageFormat.format("Table #{0} has {1} tables directly within its cells", i, count)); // Find out if the table is nested inside another table, and, if so, at what depth. int tableDepth = getNestedDepthOfTable(table); if (tableDepth > 0) System.out.println(MessageFormat.format("Table #{0} is nested inside another table at depth of {1}", i, tableDepth)); else System.out.println(MessageFormat.format("Table #{0} is a non nested table (is not a child of another table)", i)); } } /** * Calculates what level a table is nested inside other tables. * * @returns An integer containing the level the table is nested at. * 0 = Table is not nested inside any other table * 1 = Table is nested within one parent table * 2 = Table is nested within two parent tables etc.. */ private static int getNestedDepthOfTable(final Table table) { int depth = 0; Node parent = table.getAncestor(table.getNodeType()); while (parent != null) { depth++; parent = parent.getAncestor(Table.class); } return depth; } /** * Determines if a table contains any immediate child table within its cells. * Does not recursively traverse through those tables to check for further tables. * * @returns Returns true if at least one child cell contains a table. * Returns false if no cells in the table contains a table. */ private static int getChildTableCount(final Table table) { int childTableCount = 0; for (Row row : table.getRows()) { for (Cell cell : row.getCells()) { TableCollection childTables = cell.getTables(); if (childTables.getCount() > 0) childTableCount++; } } return childTableCount; }
public CompositeNode getAncestor(java.lang.Class ancestorType)
The ancestor type matches if it is equal to ancestorType or derived from ancestorType.
ancestorType
- The object type of the ancestor to retrieve.Example:
Shows how to find out if a tables are nested.Document doc = new Document(getMyDir() + "Nested tables.docx"); NodeCollection tables = doc.getChildNodes(NodeType.TABLE, true); for (int i = 0; i < tables.getCount(); i++) { Table table = (Table) tables.get(i); // Find out if any cells in the table have other tables as children. int count = getChildTableCount(table); System.out.print(MessageFormat.format("Table #{0} has {1} tables directly within its cells", i, count)); // Find out if the table is nested inside another table, and, if so, at what depth. int tableDepth = getNestedDepthOfTable(table); if (tableDepth > 0) System.out.println(MessageFormat.format("Table #{0} is nested inside another table at depth of {1}", i, tableDepth)); else System.out.println(MessageFormat.format("Table #{0} is a non nested table (is not a child of another table)", i)); } } /** * Calculates what level a table is nested inside other tables. * * @returns An integer containing the level the table is nested at. * 0 = Table is not nested inside any other table * 1 = Table is nested within one parent table * 2 = Table is nested within two parent tables etc.. */ private static int getNestedDepthOfTable(final Table table) { int depth = 0; Node parent = table.getAncestor(table.getNodeType()); while (parent != null) { depth++; parent = parent.getAncestor(Table.class); } return depth; } /** * Determines if a table contains any immediate child table within its cells. * Does not recursively traverse through those tables to check for further tables. * * @returns Returns true if at least one child cell contains a table. * Returns false if no cells in the table contains a table. */ private static int getChildTableCount(final Table table) { int childTableCount = 0; for (Row row : table.getRows()) { for (Cell cell : row.getCells()) { TableCollection childTables = cell.getTables(); if (childTables.getCount() > 0) childTableCount++; } } return childTableCount; }
public java.lang.String getText()
The returned string includes all control and special characters as described in
Example:
Shows how to construct an Aspose.Words document by hand.Document doc = new Document(); // A blank document contains one section, one body and one paragraph. // Call the "RemoveAllChildren" method to remove all those nodes, // and end up with a document node with no children. doc.removeAllChildren(); // This document now has no composite child nodes that we can add content to. // If we wish to edit it, we will need to repopulate its node collection. // First, create a new section, and then append it as a child to the root document node. Section section = new Section(doc); doc.appendChild(section); // Set some page setup properties for the section. section.getPageSetup().setSectionStart(SectionStart.NEW_PAGE); section.getPageSetup().setPaperSize(PaperSize.LETTER); // A section needs a body, which will contain and display all its contents // on the page between the section's header and footer. Body body = new Body(doc); section.appendChild(body); // Create a paragraph, set some formatting properties, and then append it as a child to the body. Paragraph para = new Paragraph(doc); para.getParagraphFormat().setStyleName("Heading 1"); para.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER); body.appendChild(para); // Finally, add some content to do the document. Create a run, // set its appearance and contents, and then append it as a child to the paragraph. Run run = new Run(doc); run.setText("Hello World!"); run.getFont().setColor(Color.RED); para.appendChild(run); Assert.assertEquals("Hello World!", doc.getText().trim()); doc.save(getArtifactsDir() + "Section.CreateManually.docx");
Example:
Shows how to use control characters.Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); // Insert paragraphs with text with DocumentBuilder. builder.writeln("Hello world!"); builder.writeln("Hello again!"); // Converting the document to text form reveals that control characters // represent some of the document's structural elements, such as page breaks. Assert.assertEquals(MessageFormat.format("Hello world!{0}", ControlChar.CR) + MessageFormat.format("Hello again!{0}", ControlChar.CR) + ControlChar.PAGE_BREAK, doc.getText()); // When converting a document to string form, // we can omit some of the control characters with the Trim method. Assert.assertEquals(MessageFormat.format("Hello world!{0}", ControlChar.CR) + "Hello again!", doc.getText().trim());
public Node nextPreOrder(Node rootNode)
rootNode
- The top node (limit) of traversal.Example:
Shows how to traverse the document's node tree using the pre-order traversal algorithm, and delete any encountered shape with an image.Document doc = new Document(getMyDir() + "Images.docx"); ArrayList<Shape> shapes = (ArrayList<Shape>) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); Assert.assertEquals(9, IterableUtils.countMatches(shapes, s -> { try { return s.hasImage(); } catch (Exception e) { e.printStackTrace(); } return false; })); Node curNode = doc; while (curNode != null) { Node nextNode = curNode.nextPreOrder(doc); if (curNode.previousPreOrder(doc) != null && nextNode != null) Assert.assertEquals(curNode, nextNode.previousPreOrder(doc)); if (curNode.getNodeType() == NodeType.SHAPE && ((Shape) curNode).hasImage()) curNode.remove(); curNode = nextNode; } shapes = (ArrayList<Shape>) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); Assert.assertEquals(0, IterableUtils.countMatches(shapes, s -> { try { return s.hasImage(); } catch (Exception e) { e.printStackTrace(); } return false; }));
public Node previousPreOrder(Node rootNode)
rootNode
- The top node (limit) of traversal.Example:
Shows how to traverse the document's node tree using the pre-order traversal algorithm, and delete any encountered shape with an image.Document doc = new Document(getMyDir() + "Images.docx"); ArrayList<Shape> shapes = (ArrayList<Shape>) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); Assert.assertEquals(9, IterableUtils.countMatches(shapes, s -> { try { return s.hasImage(); } catch (Exception e) { e.printStackTrace(); } return false; })); Node curNode = doc; while (curNode != null) { Node nextNode = curNode.nextPreOrder(doc); if (curNode.previousPreOrder(doc) != null && nextNode != null) Assert.assertEquals(curNode, nextNode.previousPreOrder(doc)); if (curNode.getNodeType() == NodeType.SHAPE && ((Shape) curNode).hasImage()) curNode.remove(); curNode = nextNode; } shapes = (ArrayList<Shape>) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); Assert.assertEquals(0, IterableUtils.countMatches(shapes, s -> { try { return s.hasImage(); } catch (Exception e) { e.printStackTrace(); } return false; }));
public void remove()
Example:
Shows how to delete all shapes with images from a document.Document doc = new Document(getMyDir() + "Images.docx"); ArrayList<Shape> shapes = (ArrayList<Shape>) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); Assert.assertEquals(9, IterableUtils.countMatches(shapes, s -> { try { return s.hasImage(); } catch (Exception e) { e.printStackTrace(); } return false; })); for (Shape shape : shapes) if (shape.hasImage()) shape.remove(); shapes = (ArrayList<Shape>) IterableUtils.toList(doc.getChildNodes(NodeType.SHAPE, true)); Assert.assertEquals(0, IterableUtils.countMatches(shapes, s -> { try { return s.hasImage(); } catch (Exception e) { e.printStackTrace(); } return false; }));
Example:
Shows how to remove all child nodes of a specific type from a composite node.Document doc = new Document(getMyDir() + "Tables.docx"); Assert.assertEquals(2, doc.getChildNodes(NodeType.TABLE, true).getCount()); Node curNode = doc.getFirstSection().getBody().getFirstChild(); while (curNode != null) { // Save the next sibling node as a variable in case we want to move to it after deleting this node. Node nextNode = curNode.getNextSibling(); // A section body can contain Paragraph and Table nodes. // If the node is a Table, remove it from the parent. if (curNode.getNodeType() == NodeType.TABLE) { curNode.remove(); } curNode = nextNode; } Assert.assertEquals(0, doc.getChildNodes(NodeType.TABLE, true).getCount());
public java.lang.String toString(SaveOptions saveOptions) throws java.lang.Exception
saveOptions
- Specifies the options that control how the node is saved.Example:
Exports the content of a node to String in HTML format.Document doc = new Document(getMyDir() + "Document.docx"); Node node = doc.getLastSection().getBody().getLastParagraph(); // When we call the ToString method using the html SaveFormat overload, // it converts the node's contents to their raw html representation. Assert.assertEquals("<p style=\"margin-top:0pt; margin-bottom:8pt; line-height:108%; font-size:12pt\">" + "<span style=\"font-family:'Times New Roman'\">Hello World!</span>" + "</p>", node.toString(SaveFormat.HTML)); // We can also modify the result of this conversion using a SaveOptions object. HtmlSaveOptions saveOptions = new HtmlSaveOptions(); saveOptions.setExportRelativeFontSize(true); Assert.assertEquals("<p style=\"margin-top:0pt; margin-bottom:8pt; line-height:108%\">" + "<span style=\"font-family:'Times New Roman'\">Hello World!</span>" + "</p>", node.toString(saveOptions));
public java.lang.String toString(int saveFormat) throws java.lang.Exception
saveFormat
- A SaveFormat value.Example:
Shows how to extract the list labels of all paragraphs that are list items.Document doc = new Document(getMyDir() + "Rendering.docx"); doc.updateListLabels(); int listParaCount = 1; for (Paragraph paragraph : (Iterable<Paragraph>) doc.getChildNodes(NodeType.PARAGRAPH, true)) { // Find if we have the paragraph list. In our document, our list uses plain Arabic numbers, // which start at three and ends at six. if (paragraph.getListFormat().isListItem()) { System.out.println(MessageFormat.format("List item paragraph #{0}", listParaCount)); // This is the text we get when getting when we output this node to text format. // This text output will omit list labels. Trim any paragraph formatting characters. String paragraphText = paragraph.toString(SaveFormat.TEXT).trim(); System.out.println("Exported Text: " + paragraphText); ListLabel label = paragraph.getListLabel(); // This gets the position of the paragraph in the current level of the list. If we have a list with multiple levels, // this will tell us what position it is on that level. System.out.println("\tNumerical Id: {label.LabelValue}"); // Combine them together to include the list label with the text in the output. System.out.println("\tList label combined with text: {label.LabelString} {paragraphText}"); }
Example:
Exports the content of a node to String in HTML format.Document doc = new Document(getMyDir() + "Document.docx"); Node node = doc.getLastSection().getBody().getLastParagraph(); // When we call the ToString method using the html SaveFormat overload, // it converts the node's contents to their raw html representation. Assert.assertEquals("<p style=\"margin-top:0pt; margin-bottom:8pt; line-height:108%; font-size:12pt\">" + "<span style=\"font-family:'Times New Roman'\">Hello World!</span>" + "</p>", node.toString(SaveFormat.HTML)); // We can also modify the result of this conversion using a SaveOptions object. HtmlSaveOptions saveOptions = new HtmlSaveOptions(); saveOptions.setExportRelativeFontSize(true); Assert.assertEquals("<p style=\"margin-top:0pt; margin-bottom:8pt; line-height:108%\">" + "<span style=\"font-family:'Times New Roman'\">Hello World!</span>" + "</p>", node.toString(saveOptions));
Example:
Shows the difference between calling the GetText and ToString methods on a node.Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); builder.insertField("MERGEFIELD Field"); // GetText will retrieve the visible text as well as field codes and special characters. Assert.assertEquals("\u0013MERGEFIELD Field\u0014«Field»\u0015\f", doc.getText()); // ToString will give us the document's appearance if saved to a passed save format. Assert.assertEquals("«Field»\r\n", doc.toString(SaveFormat.TEXT));