Copy contents of of bookmark

Hi, I am trying to copy the entire contents of a bookmark from one document to the position of a bookmark in another document. Is this possible?
If I use the code below it will insert the source bookmark at the start of the paragraph containing the destination bookmark - this works fine :

NodeImporter importer = new NodeImporter(srcDoc, destDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING);
builder.moveToBookmark(destBookmark.getName());

for (Node node : (Iterable<node>)extractedNodesExclusive)
{
    Node importNode = importer.importNode(node,true);
    builder.getCurrentSection().getBody().insertBefore(importNode, builder.getCurrentParagraph()); 
} 

If I try:

builder.getCurrentSection().getBody().insertBefore(importNode, destBookmark.getBookmarkStart());


I get the error “The reference node is not a child of this node.”

The only way I can get it into the approximate spot is to insert a paragraph - but then I obviously get a carriage return in the document that I don’t want i.e:

Paragraph pg = builder.insertParagraph();

builder.getCurrentSection().getBody().insertBefore(importNode, pg);

Is there any way of doing the above without inserting a ‘paragraph’ or ‘table’?
Thanks & Regards
David

Hi David,

Thank you for inquiry.

>>I am trying to copy the entire contents of a bookmark from one document to the position of a bookmark in another document. Is this possible?

Please follow up the code snippet:

Document dsrc = new Document("c:/New Folder/source.docx");
Bookmark bookmark = dsrc.getRange().getBookmarks().get("srcmark");
Document ddist = new Document("c:/New Folder/destination.docx");
ExportBookmarkToDocument(bookmark, ddist);
private static void ExportBookmarkToDocument(Bookmark bookmark, Document targetDocument)
{
    DocumentBuilder Builder = new DocumentBuilder(targetDocument);
    Builder.moveToBookmark("bookmark1");
    Paragraph para;

    // Remove empty paragraph at the end of the docuemnt
    if (!targetDocument.getLastSection().getBody().getLastParagraph().hasChildNodes())
        targetDocument.getLastSection().getBody().getLastParagraph().remove();

    // Get node that containd BookmarkStart and BookmarkEnd
    Node currentNode = bookmark.getBookmarkStart().getParentNode();
    Node endNode = bookmark.getBookmarkEnd().getParentNode();

    Node newNode;
    // if bookmarkStart and bookmarkEnd are children of different nodes,
    // then import nodes between parent nodes of bookmark start and bookmark end
    if (currentNode != endNode)
    {
        // import nodes between BookmarkStart and BookmarkEnd Parent nodes
        while (currentNode != endNode)
        {
            newNode = (Paragraph) Builder.getDocument().importNode(currentNode, true, ImportFormatMode.USE_DESTINATION_STYLES);
            para = (Paragraph) newNode;
            for (Node node: (Iterable <Run> ) para.getChildNodes())
            {
                Builder.getCurrentParagraph().appendChild(node);
            }
            currentNode = currentNode.getNextSibling();
        }
    }

    // import node between bookmark start and bookmark end
    newNode = Builder.getDocument().importNode(currentNode, true, ImportFormatMode.USE_DESTINATION_STYLES);
    para = (Paragraph) newNode;
    for (Node node: (Iterable <Run> ) para.getChildNodes())
    {
        Builder.getCurrentParagraph().appendChild(node);
    }
    Builder.getDocument().save("c:/New Folder/out1.docx");
}

Hope this will help. In case of any ambiguity, please let me know.

Thanks for the reply but it’s not doing what I would like it to do. It appears this code will only work if the source bookmark is a paragraph. If the bookmark contains a Table it doesn’t cast to a Paragraph and if it only contains formatted text then it won’t import anything at all.

The following code (from the Aspose web site) works fine on all paragraph types but only when I insert it at the start or end of a paragraph in the destination document. I want to insert it in the middle of a paragraph at the point where this is a bookmark. Effectively how can I replace the destination bookmark contents with the source bookmark contents?

I can do this manually in Word o.k - I can select the source bookmark, copy and paste it over the destination bookmark. The destination bookmark is replaced in it’s entirety, including keeping it as a bookmark with the source bookmark name.

Thanks for your help.
David

/**
* Inserts content of the external document after the specified node.
* Section breaks and section formatting of the inserted document are ignored.
*
* @param insertAfterNode Node in the destination document after which the content
* should be inserted. This node should be a block level node (paragraph or table).
* @param srcDoc The document to insert.
*/
public static void insertDocument(Node insertAfterNode, Document srcDoc) throws Exception
{
    // Make sure that the node is either a paragraph or table.
    if ((insertAfterNode.getNodeType() != NodeType.PARAGRAPH) &
        (insertAfterNode.getNodeType() != NodeType.TABLE))
        throw new IllegalArgumentException("The destination node should be either a paragraph or table.");

    // We will be inserting into the parent of the destination paragraph.
    CompositeNode dstStory = insertAfterNode.getParentNode();

    // This object will be translating styles and lists during the import.
    NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING);

    // Loop through all sections in the source document.
    for (Section srcSection: srcDoc.getSections())
    {
        // Loop through all block level nodes (paragraphs and tables) in the body of the section.
        for (Node srcNode: (Iterable) srcSection.getBody())
        {
            // Let's skip the node if it is a last empty paragraph in a section.
            if (srcNode.getNodeType() == (NodeType.PARAGRAPH))
            {
                Paragraph para = (Paragraph) srcNode;
                if (para.isEndOfSection() && !para.hasChildNodes())
                    continue;
            }

            // This creates a clone of the node, suitable for insertion into the destination document.
            Node newNode = importer.importNode(srcNode, true);

            // Insert new node after the reference node.
            dstStory.insertAfter(newNode, insertAfterNode);
            insertAfterNode = newNode;
        }
    }
}

Hi David,

Thanks for your inquiry. First,
please note that DocumentExplorer is a very useful tool which easily
enables us to see the entire document structure. You can
find DocumentExplorer in the folder where you installed Aspose.Words
e.g. C:\Program Files (x86)\Aspose\Aspose.Words for .NET\Demos\CSharp\DocumentExplorer\bin\DocumentExplorer.exe. Below is the DOM
structure of your document as viewed with DocumentExplorer:

Secondly, Paragraph and Table nodes are Block Level Nodes, so a Paragraph can’t contain a Table as its Child Node.
However, if it still doesn’t resolve your issue then please share the input document file with us. We’ll investigate the issue at our end and guide you accordingly.

Hope this will help.

Hi,

Unfortunately I don’t have DocumentExplorer.exe as I am using the Java version, not the .NET version.

I have attached a cut-down version of two documents I would like to ‘merge’. The ‘bookmarks.doc’ document contains the bookmarks I want to merge with ‘template.doc’ to create a new document.
There are three bookmarks in the ‘bookmarks’ document - one with plain text, one with a plain paragraph and one containing a paragraph with a table that also has another bookmark (to be brought across as is). The ‘template’ document has the corresponding bookmarks where the source bookmarks need to be inserted.

Please let me know if you require any further information.
Thanks for your assistance,
David

Hi David,

Thanks for your inquiry. Please note that, by Aspose.Words design, bookmark’s nodes (BookmarkStart and BookmarksEnd) are inline. This means that BookmarkStart and BookmarkEnd can be children of paragraphs only. So, when it comes to creating Bookmarks by using Aspose.Words, you can enclose any type of nodes (e.g. Runs, Shapes etc) within BookmarkStart and BookmarkEnd in a hierarchy. Also, Aspose.Words always keeps its DOM (document object model) in a hierarchical format. For more details please visit Object model Overview. I have also attached screen shots.

Hope this will help.

Hi,

Based on what you have said in your response is it possible to get all of the content between a BookmarkStart and BookmarkEnd in one document and and import it between a BookmarkStart and BookmarkEnd in another document? When I have tried this I get the “The reference node is not a child of this node” error. If I can do this then this will resolve my problem.

Thanks
David

Hi David,
Thanks for your request. Yes, you can try using the technique described here to extract content of bookmark into a separate document:
https://forum.aspose.com/t/74740
The provided code is in C#, but I think there will not be problems to translate it to Java.
After extracting, you can use either InsertDocument or AppendDocument methods to insert content into your document:
https://docs.aspose.com/words/java/insert-and-append-documents/

Hope this will help. In case of any ambiguity, please let me know.

Hi, Unfortunately your solution will not do what I would like it to do. Your solution assumes that the destination bookmark is a bookmark of an empty paragraph. In the document I uploaded there is one bookmark that is in the middle of a paragraph. I don’t beleive it is possible to insert a new ‘document’ at this point. Also as there could be many (5 to 10) bookmarks that need to be copied from one document to another then it would be vey inefficient to create a new intermediate document every time a bookmark is copied.
Is it not possible to copy the source bookmark and all it’s child nodes to the location of a bookmark in the destination document - even if the destination bookmark is in the middle of a paragraph?
Thanks
David

Hi David,

Thank you for inquiry. By Aspose.Words design, there is no direct way to achieve this. Moreover, you can hold new intermediate document within Document object.

I hope, this will help.