We have some code that creates a new document from a template containing bookmarks. This worked in Words 17.4, but fails in 18.9 with “java.lang.ClassCastException: com.aspose.words.BookmarkEnd cannot be cast to com.aspose.words.CompositeNode”
The code is based on the method described in Extract Selected Content Between Nodes in Java|Aspose.Words for Java
The method is:
private void writeStandardsSection(Document template, DocumentBuilder builder, List<Map<String, Object>> standards, BufferedImage compliantImage, BufferedImage noncompliantImage) {
try {
Bookmark standardsBookmark = template.getRange().getBookmarks().get("standardsTable");
Document standardsTemplate = generateDocumentFromBookmark(template, standardsBookmark);
standardsBookmark.setText("");
private static Document generateDocumentFromBookmark(Document srcDoc, Bookmark bookmark) throws Exception {
if (bookmark == null) {
return null;
}
ArrayList<CompositeNode> nodes = extractContent(bookmark.getBookmarkStart(), bookmark.getBookmarkEnd(), true);
...
private static ArrayList<CompositeNode> extractContent(Node originalStartNode, Node originalEndNode, boolean isInclusive) throws Exception {
// Create a list to store the extracted nodes.
ArrayList<CompositeNode> nodes = new ArrayList<>();
// Keep a record of the original nodes passed to this method so we can split marker nodes if needed.
Node startNode = originalStartNode;
Node endNode = originalEndNode;
// Extract content based on block level nodes (paragraphs and tables). Traverse through parent nodes to find them.
// We will split the content of first and last nodes depending if the marker nodes are inline
while (startNode.getParentNode().getNodeType() != NodeType.BODY)
startNode = startNode.getParentNode();
while (endNode.getParentNode().getNodeType() != NodeType.BODY)
endNode = endNode.getParentNode();
boolean isExtracting = true;
boolean isStartingNode = true;
boolean isEndingNode;
// The current node we are extracting from the document.
Node currNode = startNode;
// Begin extracting content. Process all block level nodes and specifically split the first and last nodes when needed so paragraph formatting is retained.
// Method is little more complex than a regular extractor as we need to factor in extracting using inline nodes, fields, bookmarks etc as to make it really useful.
while (isExtracting) {
// Clone the current node and its children to obtain a copy.
CompositeNode cloneNode = (CompositeNode) currNode.deepClone(true);
isEndingNode = currNode.equals(endNode);
if (isStartingNode || isEndingNode) {
// We need to process each marker separately so pass it off to a separate method instead.
if (isStartingNode) {
processMarker(cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode);
isStartingNode = false;
}
// Conditional needs to be separate as the block level start and end markers maybe the same node.
if (isEndingNode) {
processMarker(cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode);
isExtracting = false;
}
} else
// Node is not a start or end marker, simply add the copy to the list.
nodes.add(cloneNode);
// Move to the next node and extract it. If next node is null that means the rest of the content is found in a different section.
if (currNode.getNextSibling() == null && isExtracting) {
// Move to the next section.
Section nextSection = (Section) currNode.getAncestor(NodeType.SECTION).getNextSibling();
currNode = nextSection.getBody().getFirstChild();
} else {
// Move to the next node in the body.
currNode = currNode.getNextSibling();
}
}
// Return the nodes between the node markers.
return nodes;
}
We couldn’t find anything in the release notes, so we’re unsure how this should now be done. Does anyone have any suggestions, please?