We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

Issue with copying over custom style inside a bookmark

I have a word document that has a block of text (contained inside a bookmark), which has a custom style (e.g., “MyCustomStyle”) associated to it. When I use Aspose.Words to export the bookmark to a another document, it preserves the text & the formatting, but does not preserve the custom style name (“MyCustomStyle”). The reason why we need this custom style preserved is that we use document conversion services to convert the target document to a web page.
Has anyone seen this issue before? Any ideas for me to try here?
Thanks! (see code below)
-------------------------------------------------------------------------------

// This method is used to export a bookmark to a document.
private void ExportBookmarkToDocument(Bookmark bookmark, ref Aspose.Words.Document targetDocument)
{
    // Get node that containd BookmarkStart and BookmarkEnd
    Node currentNode = bookmark.BookmarkStart.ParentNode;
    Node endNode = bookmark.BookmarkEnd.ParentNode;
    // 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 part of first paragraph if this is needed
        if (!(currentNode as CompositeNode).FirstChild.Equals(bookmark.BookmarkStart))
        {
            CompositeNode firstNode = (CompositeNode)targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            while (firstNode.HasChildNodes)
            {
                if (firstNode.FirstChild.NodeType != NodeType.BookmarkStart)
                    firstNode.FirstChild.Remove();
                else if ((firstNode.FirstChild as BookmarkStart).Name != bookmark.Name)
                    firstNode.FirstChild.Remove();
                else
                    break;
            }
            targetDocument.FirstSection.Body.AppendChild(firstNode);
            currentNode = currentNode.NextSibling;
        }
        // import nodes between BookmarkStart and BookmarkEnd Parent nodes
        while (currentNode != endNode)
        {
            Node newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            targetDocument.FirstSection.Body.AppendChild(newNode);
            currentNode = currentNode.NextSibling;
        }
        if ((endNode as CompositeNode).LastChild.Equals(bookmark.BookmarkEnd))
        {
            targetDocument.FirstSection.Body.AppendChild(targetDocument.ImportNode(endNode, true, ImportFormatMode.KeepSourceFormatting));
        }
        // import part of last paragraph if this is needed
        else
        {
            CompositeNode lastNode = (CompositeNode)targetDocument.ImportNode(endNode, true, ImportFormatMode.KeepSourceFormatting);
            while (lastNode.HasChildNodes)
            {
                if (lastNode.LastChild.NodeType != NodeType.BookmarkEnd)
                    lastNode.LastChild.Remove();
                else if ((lastNode.LastChild as BookmarkEnd).Name != bookmark.Name)
                    lastNode.LastChild.Remove();
                else
                    break;
            }
            targetDocument.FirstSection.Body.AppendChild(lastNode);
        }
    }
    // else import nodes between bookmark start and bookmark end
    else
    {
        currentNode = bookmark.BookmarkStart.NextSibling;
        // import nodes between BookmarkStart and BookmarkEnd
        while (currentNode != bookmark.BookmarkEnd)
        {
            Node newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            targetDocument.FirstSection.Body.FirstParagraph.AppendChild(newNode);
            currentNode = currentNode.NextSibling;
        }
    }
}

Hi
Thanks for your request. Does the destination document contain the same custom style? If so you can try using ImportFormatMode.UseDestinationStyles instead ImportFormatMode.KeepSourceFormatting
Hope this helps.
Best regards.

Good thought, but no, the destination document doesn’t contain the same style. Also, I (the code) would have no way of knowing what styles to specifically create in the destination document (if I was to try the route of porting over the custom style)… or would I?
Is there a way I can extract all custom style names from the source document, and create those in the destination document?

Hi
Anyway, please try using ImportFormatMode.UseDestinationStyles. In this case Aspose.Words uses the destination document styles and copy new styles, if there is no corresponding style in the destination document. I think this should help you.
Best regards.

Alex,
I tried what you suggested with the ImportFormatMode.UseDestinationStyles, but it didn’t copy over the styles (old or new).
I looked over the Aspose.Words documentation, and didn’t see a way to copy/export styles from one document to another. Do you know of any way to do this? (If there is a way, I can simply copy all styles from the source document to the target document).
Any other suggestions would be welcome as well.
Thanks!

Hi
Thanks for your request. Could you please attach your documents for testing (source and destination)? I will further investigate your issue and provide you more information.
There is no way to copy styles between documents, however, when you import some node from another document, style will be copied. I tested this on my side and all works as expected.
Best regards.

Alex,
I’ve attached the source document here, though the target document is created on the fly using the code below. A few things here that I consider suspect:

  1. The source document is a “.doc” file, and the newly created target document is saved as a “.docx” file. (perhaps some compatibility issue between different formats of Word documents?)
  2. The source document does contain some macros.
    Any insight/assistance you could provide here would be greatly appreciated! Thanks!
    ------
....Bookmark bookmark = sourceDocument.Range.Bookmarks[bookmarkName];
// create new document
Aspose.Words.Document newDocument = new Aspose.Words.Document();
// copy the contents of the bookmark to the new document
ExportBookmarkToDocument(bookmark, ref newDocument);
....
// This method is used to export a bookmark to a document.
private void ExportBookmarkToDocument(Bookmark bookmark, ref Aspose.Words.Document targetDocument)
{
    // Get node that containd BookmarkStart and BookmarkEnd
    Node currentNode = bookmark.BookmarkStart.ParentNode;
    Node endNode = bookmark.BookmarkEnd.ParentNode;
    // 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 part of first paragraph if this is needed
        if (!(currentNode as CompositeNode).FirstChild.Equals(bookmark.BookmarkStart))
        {
            CompositeNode firstNode = (CompositeNode)targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            while (firstNode.HasChildNodes)
            {
                if (firstNode.FirstChild.NodeType != NodeType.BookmarkStart)
                    firstNode.FirstChild.Remove();
                else if ((firstNode.FirstChild as BookmarkStart).Name != bookmark.Name)
                    firstNode.FirstChild.Remove();
                else
                    break;
            }
            targetDocument.FirstSection.Body.AppendChild(firstNode);
            currentNode = currentNode.NextSibling;
        }
        // import nodes between BookmarkStart and BookmarkEnd Parent nodes
        while (currentNode != endNode)
        {
            Node newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            targetDocument.FirstSection.Body.AppendChild(newNode);
            currentNode = currentNode.NextSibling;
        }
        if ((endNode as CompositeNode).LastChild.Equals(bookmark.BookmarkEnd))
        {
            targetDocument.FirstSection.Body.AppendChild(targetDocument.ImportNode(endNode, true, ImportFormatMode.KeepSourceFormatting));
        }
        // import part of last paragraph if this is needed
        else
        {
            CompositeNode lastNode = (CompositeNode)targetDocument.ImportNode(endNode, true, ImportFormatMode.KeepSourceFormatting);
            while (lastNode.HasChildNodes)
            {
                if (lastNode.LastChild.NodeType != NodeType.BookmarkEnd)
                    lastNode.LastChild.Remove();
                else if ((lastNode.LastChild as BookmarkEnd).Name != bookmark.Name)
                    lastNode.LastChild.Remove();
                else
                    break;
            }
            targetDocument.FirstSection.Body.AppendChild(lastNode);
        }
    }
    // else import nodes between bookmark start and bookmark end
    else
    {
        currentNode = bookmark.BookmarkStart.NextSibling;
        // import nodes between BookmarkStart and BookmarkEnd
        while (currentNode != bookmark.BookmarkEnd)
        {
            Node newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            targetDocument.FirstSection.Body.FirstParagraph.AppendChild(newNode);
            currentNode = currentNode.NextSibling;
        }
    }
    // accept all revisions
    targetDocument.AcceptAllRevisions();
    targetDocument.TrackRevisions = false;
    // targetDocument.Protect(ProtectionType.NoProtection);
}

Hi
Thank you for additional information. However, as I can see the document you attached does not contain any bookmark at all. Maybe you attached a wrong file.
Best regards.

It does contain a bookmark, though it’s a hidden bookmark (you’ll need to check that “Hidden” check box when you have the bookmark dialog box open). The name of the bookmark is “_412”. Please let me know if you still don’t see it & I’ll try resending.
Thanks.

I’ve actually isolated this now to the bookmark level. So what I did was the following:

  1. Created the destination document as a copy of the source document, stripping out all content (but preserving the styles).
  2. I exported the bookmark from the source document to the destination document (using the code above from the “ExportBookmarkToDocument” method).
  3. I save the destination document.
    When I open the saved destination document, I notice that it has the style definition in it, but the style is not applied to the text within the bookmark. I.e., it appears that porting over the bookmark did not preserve the custom style associated to the text within it. I’ve attached the source document here (same as the one I posted above).
    Thoughts?

Hi
Thank you for additional information. Could you please simplify your document? Please avoid using hidden content and bookmark; also remove content that is not needed to reproduce the issue.
Best regards,

Please see the attached document… it’s very basic; just a new document with some text, a new custom style (“JafarsTestStyle”). The text with the custom style applied to it is contained within the bookmark called “MyBookmark1”. I got the same results in this basic case of a simple document with simple bookmark; the custom style gets carried over to the target doucment, but style for the text doesn’t get ported over to the target document.
For your convenience, below is the code again I am using to perform the bookmark export.
Thanks!
------------------------

Bookmark bookmark = sourceDocument.Range.Bookmarks[bookmarkName];
// create new document
Aspose.Words.Document newDocument = sourceDocument.Clone();
// clear out cloned document
newDocument.RemoveAllChildren();
newDocument.RemoveMacros();
newDocument.Range.Bookmarks.Clear();
newDocument.CustomDocumentProperties.Clear();
newDocument.EnsureMinimum();
// copy the contents of the bookmark to the new document
ExportBookmarkToDocument(bookmark, ref newDocument);
...........
// This method is used to export a bookmark to a document.
private void ExportBookmarkToDocument(Bookmark bookmark, ref Aspose.Words.Document targetDocument)
{
    // Get node that containd BookmarkStart and BookmarkEnd
    Node currentNode = bookmark.BookmarkStart.ParentNode;
    Node endNode = bookmark.BookmarkEnd.ParentNode;
    // 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 part of first paragraph if this is needed
        if (!(currentNode as CompositeNode).FirstChild.Equals(bookmark.BookmarkStart))
        {
            CompositeNode firstNode = (CompositeNode)targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            while (firstNode.HasChildNodes)
            {
                if (firstNode.FirstChild.NodeType != NodeType.BookmarkStart)
                    firstNode.FirstChild.Remove();
                else if ((firstNode.FirstChild as BookmarkStart).Name != bookmark.Name)
                    firstNode.FirstChild.Remove();
                else
                    break;
            }
            targetDocument.FirstSection.Body.AppendChild(firstNode);
            currentNode = currentNode.NextSibling;
        }
        // import nodes between BookmarkStart and BookmarkEnd Parent nodes
        while (currentNode != endNode)
        {
            Node newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            targetDocument.FirstSection.Body.AppendChild(newNode);
            currentNode = currentNode.NextSibling;
        }
        if ((endNode as CompositeNode).LastChild.Equals(bookmark.BookmarkEnd))
        {
            targetDocument.FirstSection.Body.AppendChild(targetDocument.ImportNode(endNode, true, ImportFormatMode.KeepSourceFormatting));
        }
        // import part of last paragraph if this is needed
        else
        {
            CompositeNode lastNode = (CompositeNode)targetDocument.ImportNode(endNode, true, ImportFormatMode.KeepSourceFormatting);
            while (lastNode.HasChildNodes)
            {
                if (lastNode.LastChild.NodeType != NodeType.BookmarkEnd)
                    lastNode.LastChild.Remove();
                else if ((lastNode.LastChild as BookmarkEnd).Name != bookmark.Name)
                    lastNode.LastChild.Remove();
                else
                    break;
            }
            targetDocument.FirstSection.Body.AppendChild(lastNode);
        }
    }
    // else import nodes between bookmark start and bookmark end
    else
    {
        currentNode = bookmark.BookmarkStart.NextSibling;
        // import nodes between BookmarkStart and BookmarkEnd
        while (currentNode != bookmark.BookmarkEnd)
        {
            Node newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.KeepSourceFormatting);
            targetDocument.FirstSection.Body.FirstParagraph.AppendChild(newNode);
            currentNode = currentNode.NextSibling;
        }
    }
    // accept all revisions 
    targetDocument.AcceptAllRevisions();
    targetDocument.TrackRevisions = false;
    // targetDocument.Protect(ProtectionType.NoProtection);
}

Hi
Thank you for additional information. I modified code a bit. Please try using the following code:

// This method is used to export a bookmark to a document.
private void ExportBookmarkToDocument(Bookmark bookmark, ref Aspose.Words.Document targetDocument)
{
    // Get node that containd BookmarkStart and BookmarkEnd
    Node currentNode = bookmark.BookmarkStart.ParentNode;
    Node endNode = bookmark.BookmarkEnd.ParentNode;
    // 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 part of first paragraph if this is needed
        if (!(currentNode as CompositeNode).FirstChild.Equals(bookmark.BookmarkStart))
        {
            CompositeNode firstNode = (CompositeNode)targetDocument.ImportNode(currentNode, true, ImportFormatMode.UseDestinationStyles);
            while (firstNode.HasChildNodes)
            {
                if (firstNode.FirstChild.NodeType != NodeType.BookmarkStart)
                    firstNode.FirstChild.Remove();
                else if ((firstNode.FirstChild as BookmarkStart).Name != bookmark.Name)
                    firstNode.FirstChild.Remove();
                else
                    break;
            }
            targetDocument.FirstSection.Body.AppendChild(firstNode);
            currentNode = currentNode.NextSibling;
        }
        // import nodes between BookmarkStart and BookmarkEnd Parent nodes
        while (currentNode != endNode)
        {
            Node newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.UseDestinationStyles);
            targetDocument.FirstSection.Body.AppendChild(newNode);
            currentNode = currentNode.NextSibling;
        }
        if ((endNode as CompositeNode).LastChild.Equals(bookmark.BookmarkEnd))
        {
            targetDocument.FirstSection.Body.AppendChild(targetDocument.ImportNode(endNode, true, ImportFormatMode.UseDestinationStyles));
        }
        // import part of last paragraph if this is needed
        else
        {
            CompositeNode lastNode = (CompositeNode)targetDocument.ImportNode(endNode, true, ImportFormatMode.UseDestinationStyles);
            while (lastNode.HasChildNodes)
            {
                if (lastNode.LastChild.NodeType != NodeType.BookmarkEnd)
                    lastNode.LastChild.Remove();
                else if ((lastNode.LastChild as BookmarkEnd).Name != bookmark.Name)
                    lastNode.LastChild.Remove();
                else
                    break;
            }
            targetDocument.FirstSection.Body.AppendChild(lastNode);
        }
    }
    // else import nodes between bookmark start and bookmark end
    else
    {
        Node newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.UseDestinationStyles);
        targetDocument.FirstSection.Body.AppendChild(newNode);
    }
}

Hope this helps.
Best regards.

I applied your code, and it works with 1 minor issue: it add an extra line break before the bookmark (which for me is an issue as this will be converted to a web page, and that will be an extra line break there). I’ve attached the source document I used to test this, and also the target document created by the Export method.
Thanks.

Hi
Thanks for your request. I simplified the code. Please try using the following code:

// This method is used to export a bookmark to a document.
private void ExportBookmarkToDocument(Bookmark bookmark, ref Aspose.Words.Document targetDocument)
{
    // Remove empty paragraph at the end of the docuemnt
    if (!targetDocument.LastSection.Body.LastParagraph.HasChildNodes)
        targetDocument.LastSection.Body.LastParagraph.Remove();
    // Get node that containd BookmarkStart and BookmarkEnd
    Node currentNode = bookmark.BookmarkStart.ParentNode;
    Node endNode = bookmark.BookmarkEnd.ParentNode;
    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 = targetDocument.ImportNode(currentNode, true, ImportFormatMode.UseDestinationStyles);
            targetDocument.LastSection.Body.AppendChild(newNode);
            currentNode = currentNode.NextSibling;
        }
    }
    // import node between bookmark start and bookmark end
    newNode = targetDocument.ImportNode(currentNode, true, ImportFormatMode.UseDestinationStyles);
    targetDocument.LastSection.Body.AppendChild(newNode);
}

Hope this helps.
Best regards.

Thanks for the code; it seems to be working fine on the surface, though I’m gonna give it a more rigorous QA test. I also tried adding the following code below to the orginal code, which also did the trick:

// remove all preceding carriage return
foreach (Node childNode in targetDocument.FirstSection.Body.ChildNodes)
{
    if (childNode.Range.Text.Equals("\r"))
    {
        childNode.Remove();
    }
    else
    {
        break;
    }
}

Though I like your code better (cleaner). Thanks again for your help here!!