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

# Numbering Formatting lost in document

I have a problem with numbering formating durring proccesing of the word document.

I load some word document that contains numbering format (See attachment). I run through all word bookmarks and perform the following code:

mDocument.Range.Bookmarks["START" + wField.Id].Text = mDocument.Range.Bookmarks["START" + wField.Id].Text.Replace("[", " ").Replace("]", " ");

As you can see from the attachment Bookmark text in VS does not contain numering.

Is this a bug? Or i am doing something wrong?

Hi

Thanks for your request. no, this is not a bug. List labels are no stored in the document, they are calculated by MS Word on the fly. That is why you do not see them.

If you need to get a list label of the paragraph, you can use Paragraph.ListLabel property:

http://www.aspose.com/documentation/.net-components/aspose.words-for-.net/aspose.words.paragraph.listlabel.html

Hope this helps.

Best regards,

The problem is that after i run the code that i mentioned in the post and save the document, word desnt calculates the numbering anymore. When i open this document with word the numbering is not shown.

See attachment (before and after).

How can i solve this problem? All that i need is to remove brackets [ ] from the begining and from the end of the bookmark text?

Hello

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thanks for your request. The brackets around bookmark are invisible during rendering/printing etc. It is MS Word options. If you would like to hide brackets, you should go to “Word Options” -> “Advanced” and uncheck “Show Bookmarks” option. After these changes, brackets will become invisible in MS Word.

Best regards,

These are not word bookmark brackets. These are brackets that we are adding in code to emphasize to the user where he can enter a text. This part is done in client side where we are using word. At the end of the process we are removing them in code. The code that removes these brackets will run in server and we want to use aspose for that. But we encountered several problems that we are trying to solve.

Hello

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Best regards,

Sure,

see attachments.

Hello<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thank you for additional information. Please try using the suggestions provided here:

Best regards,

Thank you.

That is exactly the problem here. When i am removing brackets from bookmark that points to the text with numbering and save the document, numbering is not displayed anymore. Did you succeeded to reproduce this problem with the attached document?

Hello

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

foreach (Bookmark bookmark in doc.Range.Bookmarks)

{

Node curNode = bookmark.BookmarkStart;

while (curNode != null && !curNode.Equals(bookmark.BookmarkEnd))

{

//Move to next node

Node nextNode = curNode.NextPreOrder(doc);

//Check whether current contains end node

if (curNode.IsComposite)

{

if (!((CompositeNode)curNode).GetChildNodes(NodeType.Any, true).Contains(bookmark.BookmarkEnd) &&

!((CompositeNode)curNode).GetChildNodes(NodeType.Any, true).Contains(bookmark.BookmarkStart))

{

nextNode = curNode.NextSibling;

curNode.Range.Replace(new Regex("[\$\$]"), " ");

}

}

else

{

curNode.Range.Replace(new Regex("[\$\$]"), " ");

}

curNode = nextNode;

}

}

Best regards,

Thank you very much!

This code looks very promising. Looks like it solved all problems i mentioned before (numbering, scroll and right to left issue). I will perform more testing next week. Thank you again.

Just another question regarding the numbering format. Is there a way to copy all bookmark text including formating (like numbering) from one bookmark to another?

Hello

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thanks for your inquiry. Of course, Aspose.Words provides functionality for easy copying and moving fragments between Microsoft Word documents. This is known as "importing nodes". Before you can insert a fragment from one document into another, you need to "import" it. Importing creates a deep clone of the original node, ready to be inserted into the destination document.

http://www.aspose.com/documentation/.net-components/aspose.words-for-.net/aspose.words.nodeimporter.html

Hope this helps.

Best regards,

Oh, i don’t mean copying fragments between different documents. I talking about copying bookmark’s content from one bookmark to another within the same document, but i cant use bookmark’s 'Text" property because in this way i cant copy formating (like numbering). Is there a way copy all it’s content including formating?

i tried ti use the following code example that i found on this forum:

public Document ExtractContentFromBookmark(Document srcDoc, string bookmarkName)
{
Bookmark bookmark = srcDoc.Range.Bookmarks[bookmarkName];
if (bookmark == null)
throw new Exception(“There is no bookmark with specified name”);

Paragraph startNode = (Paragraph)bookmark.BookmarkStart.GetAncestor(NodeType.Paragraph);
Paragraph endNode = (Paragraph)bookmark.BookmarkEnd.GetAncestor(NodeType.Paragraph);

// Make sure that start and end nodes are children of the same story.
if (!startNode.ParentNode.Equals(endNode.ParentNode))
throw new Exception(“Start and end nodes should be children of the same story”);

// Clone the original document, this is needed to preserve styles of the original document
Document dstDoc = srcDoc.Clone();
dstDoc.RemoveAllChildren();

// The destination document should contain at lean one section.
dstDoc.EnsureMinimum();
dstDoc.FirstSection.Body.RemoveAllChildren();

// We will use NodeImporter to import nodes from one document to another.
NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.UseDestinationStyles);

Node currNode = startNode;
Node dstNode;
// Copy content
while (currNode != null && !currNode.Equals(endNode))
{
// Import node
dstNode = importer.ImportNode(currNode, true);

dstDoc.LastSection.Body.AppendChild(dstNode);

// Move to the next node
Node nextNode = currNode.NextSibling;
//Move to the next section
if (nextNode == null && currNode.ParentNode.NodeType == NodeType.Body)
{
Node sect = currNode.GetAncestor(NodeType.Section);
if (sect.NextSibling != null)
{
dstNode = importer.ImportNode(sect.NextSibling, true);
dstDoc.AppendChild(dstNode);
dstDoc.LastSection.Body.RemoveAllChildren();
nextNode = ((Section)sect.NextSibling).Body.FirstChild;
}
}

currNode = nextNode;
}
// If the bookmark end is the last child of the last paragraph we need to copy it as well.
if (endNode.LastChild.Equals(bookmark.BookmarkEnd))
{
dstNode = dstDoc.ImportNode(endNode, true, ImportFormatMode.UseDestinationStyles);
dstDoc.LastSection.Body.AppendChild(dstNode);
}

dstDoc.Save(“C:\Temp\Temp.doc”);

return dstDoc;
}

public void InsertDocumentAtBookmark(string bookmarkName, Document dstDoc, Document srcDoc)
{
NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.UseDestinationStyles);
//Create DocumentBuilder
DocumentBuilder builder = new DocumentBuilder(dstDoc);
//Move cursor to bookmark and insert paragraph break
builder.MoveToBookmark(bookmarkName);
builder.Writeln();
// If current paragraph is a list item, we should clear its formating.
if (builder.CurrentParagraph.IsListItem)
builder.ListFormat.RemoveNumbers();
//Content of srcdoc will be inserted after this node
Node insertAfterNode = builder.CurrentParagraph.PreviousSibling;
//Content of first paragraph of srcDoc will be apended to this parafraph
Paragraph insertAfterParagraph = null;
if (insertAfterNode.NodeType == NodeType.Paragraph)
insertAfterParagraph = (Paragraph)insertAfterNode;
//Content of last paragraph of srcDoc will be apended to this parafraph
Paragraph insertBeforeParagraph = builder.CurrentParagraph;
//We will be inserting into the parent of the destination paragraph.
CompositeNode dstStory = insertAfterNode.ParentNode;
//Remove empty paragraphs from the end of document
while (!((CompositeNode)srcDoc.LastSection.Body.LastChild).HasChildNodes)
{
srcDoc.LastSection.Body.LastParagraph.Remove();
if (srcDoc.LastSection.Body.LastChild == null)
break;
}
//Loop through all sections in the source document.

foreach (Section srcSection in srcDoc.Sections)
{
//Loop through all block level nodes (paragraphs and tables) in the body of the section.
for (int nodeIdx = 0; nodeIdx < srcSection.Body.ChildNodes.Count; nodeIdx++)
{
Node srcNode = srcSection.Body.ChildNodes[nodeIdx];
//Do not insert node if it is a last empty paragarph in the section.
Paragraph para = null;
if (srcNode.NodeType == NodeType.Paragraph)
para = (Paragraph)srcNode;

if ((para != null) && para.IsEndOfSection && (!para.HasChildNodes))
break;

//If current paragraph is first paragraph of srcDoc
//then appent its content to insertAfterParagraph
bool nodeInserted = false;
if (para != null && para.Equals(srcDoc.FirstSection.Body.FirstChild))
{
nodeInserted = true; // set this flag to know that we already processed this node.
for (int i = 0; i < para.ChildNodes.Count; i++)
{
Node node = para.ChildNodes[i];
Node dstNode = importer.ImportNode(node, true);
insertAfterParagraph.AppendChild(dstNode);
}

//If subdocument contains only one paragraph
//then copy content of insertBeforeParagraph to insertAfterParagraph
//and remove insertBeforeParagraph
if (srcDoc.FirstSection.Body.FirstParagraph.Equals(srcDoc.LastSection.Body.LastChild))
{
while (insertBeforeParagraph.HasChildNodes)
insertAfterParagraph.AppendChild(insertBeforeParagraph.FirstChild);

insertBeforeParagraph.Remove();
}
}
//If current paragraph is last paragraph of srcDoc
//then appent its content to insertBeforeParagraph
if (para != null && para.Equals(srcDoc.LastSection.Body.LastChild))
{
nodeInserted = true; // set this flag to know that we already processed this node.
Node previouseNode = null;
for (int i = 0; i < para.ChildNodes.Count; i++)
{
Node node = para.ChildNodes[i];
Node dstNode = importer.ImportNode(node, true);
if (previouseNode == null)
insertBeforeParagraph.InsertBefore(dstNode, insertBeforeParagraph.FirstChild);
else
insertBeforeParagraph.InsertAfter(dstNode, previouseNode);

previouseNode = dstNode;
}
}

if (!nodeInserted)
{
//This creates a clone of the node, suitable for insertion into the destination document.
Node newNode = dstDoc.ImportNode(srcNode, true);
//Insert new node after the reference node.
dstStory.InsertAfter(newNode, insertAfterNode);
insertAfterNode = newNode;
}
}
}
}

I used it in this way:

private void button2_Click(object sender, EventArgs e)
{
Document doc = new Document(“C:\Temp\Source.doc”);
DocumentBuilder builder = new DocumentBuilder(doc);

builder.MoveToBookmark(“START12634388900839794510F”);

Document docTmp = ExtractContentFromBookmark(doc, “START23634388903025253034F”);

InsertDocumentAtBookmark(“START12634388900839794510F”, doc, docTmp);

doc.Save(“C:\Temp\AfterCopy.doc”);
}

But i got several problems.
1. Numbering is wrong.
2. Last line lost its bullets.

Can you please check what is wrong with a code?

i succeed to solve the problem that i mentioned in previous post with the another code that i found on this forum. My goal is to take bookmark’s content with all formating and append it to another bookmark (that already may have some content). I am using for this the following code:

private void button3_Click(object sender, EventArgs e)
{
Document doc = new Document(“C:\Temp\Source2.doc”);

Document docTmp1 = ExtractContentFromBookmark(doc, “START57634309578388128307F”);
Document docTmp2 = ExtractContentFromBookmark(doc, “START93634390078433273520F”);

docTmp1.AppendDocument(docTmp2, ImportFormatMode.KeepSourceFormatting);

doc.Range.Bookmarks[“START92634390078323432537F”].Text = " ";

InsertDocumentAtBookmark(“START92634390078323432537F”, doc, docTmp1);

doc.Save(“C:\Temp\AfterCopy4.doc”);
}

public Document ExtractContentFromBookmark(Document srcDoc, string bookmarkName)
{
Bookmark bookmark = srcDoc.Range.Bookmarks[bookmarkName];
if (bookmark == null)
throw new Exception(“There is no bookmark with specified name”);

Paragraph startNode = (Paragraph)bookmark.BookmarkStart.GetAncestor(NodeType.Paragraph);
Paragraph endNode = (Paragraph)bookmark.BookmarkEnd.GetAncestor(NodeType.Paragraph);

// Make sure that start and end nodes are children of the same story.
if (!startNode.ParentNode.Equals(endNode.ParentNode))
throw new Exception(“Start and end nodes should be children of the same story”);

// Clone the original document, this is needed to preserve styles of the original document
Document dstDoc = srcDoc.Clone();
dstDoc.RemoveAllChildren();

// The destination document should contain at lean one section.
dstDoc.EnsureMinimum();
dstDoc.FirstSection.Body.RemoveAllChildren();

// We will use NodeImporter to import nodes from one document to another.
NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.UseDestinationStyles);

Node currNode = startNode;
Node dstNode;
// Copy content
while (currNode != null && !currNode.Equals(endNode))
{
// Import node
dstNode = importer.ImportNode(currNode, true);

dstDoc.LastSection.Body.AppendChild(dstNode);

// Move to the next node
Node nextNode = currNode.NextSibling;
//Move to the next section
if (nextNode == null && currNode.ParentNode.NodeType == NodeType.Body)
{
Node sect = currNode.GetAncestor(NodeType.Section);
if (sect.NextSibling != null)
{
dstNode = importer.ImportNode(sect.NextSibling, true);
dstDoc.AppendChild(dstNode);
dstDoc.LastSection.Body.RemoveAllChildren();
nextNode = ((Section)sect.NextSibling).Body.FirstChild;
}
}

currNode = nextNode;
}
// If the bookmark end is the last child of the last paragraph we need to copy it as well.
if (endNode.LastChild.Equals(bookmark.BookmarkEnd))
{
dstNode = dstDoc.ImportNode(endNode, true, ImportFormatMode.UseDestinationStyles);
dstDoc.LastSection.Body.AppendChild(dstNode);
}

return dstDoc;
}

public void InsertDocumentAtBookmark(string bookmarkName, Document dstDoc, Document srcDoc)
{
NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KeepSourceFormatting);
//Create DocumentBuilder
DocumentBuilder builder = new DocumentBuilder(dstDoc);
//Move cursor to bookmark and insert paragraph break
builder.MoveToBookmark(bookmarkName);
builder.Writeln();
// If current paragraph is a list item, we should clear its formating.
if (builder.CurrentParagraph.IsListItem)
builder.ListFormat.RemoveNumbers();
//Content of srcdoc will be inserted after this node
Node insertAfterNode = builder.CurrentParagraph.PreviousSibling;
//Content of first paragraph of srcDoc will be apended to this parafraph
Paragraph insertAfterParagraph = null;
if (insertAfterNode.NodeType == NodeType.Paragraph)
insertAfterParagraph = (Paragraph)insertAfterNode;
//Content of last paragraph of srcDoc will be apended to this parafraph
Paragraph insertBeforeParagraph = builder.CurrentParagraph;
//We will be inserting into the parent of the destination paragraph.
CompositeNode dstStory = insertAfterNode.ParentNode;
//Remove empty paragraphs from the end of document
while (!((CompositeNode)srcDoc.LastSection.Body.LastChild).HasChildNodes)
{
srcDoc.LastSection.Body.LastParagraph.Remove();
if (srcDoc.LastSection.Body.LastChild == null)
break;
}

Node originalInsertNode = insertAfterNode;

bool isFirstNode = true;

// Loop through all sections in the source document.
foreach (Section srcSection in srcDoc.Sections)
{
// Loop through all block level nodes (paragraphs and tables) in the body of the section.
foreach (CompositeNode srcNode in srcSection.Body)
{
// Let’s skip the node if it is a last empty paragarph in a section.
if (srcNode.NodeType.Equals(NodeType.Paragraph))
{
Paragraph para = (Paragraph)srcNode;
if (para.IsEndOfSection && !para.HasChildNodes)
continue;
}

bool processedNode = false;

if (isFirstNode)
{
if (srcNode.NodeType == NodeType.Paragraph && insertAfterNode.NodeType != NodeType.Table)
{
Node currentInlineNode = null;
Paragraph insertParagraph = null;

if (insertAfterNode.NodeType == NodeType.Paragraph)
{
currentInlineNode = ((Paragraph)insertAfterNode).LastChild;
insertParagraph = (Paragraph)insertAfterNode;
}
else if (insertAfterNode.ParentNode.NodeType == NodeType.Paragraph)
{
currentInlineNode = insertAfterNode;
insertParagraph = (Paragraph)insertAfterNode.ParentNode;
}

foreach (Node node in srcNode.ChildNodes)
{
Node inlineNode = importer.ImportNode(node, true);
insertParagraph.InsertAfter(inlineNode, currentInlineNode);
currentInlineNode = inlineNode;
}

processedNode = true;

}

isFirstNode = false;
}

if (!processedNode)
{
// 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;
}
}
}

if (originalInsertNode is CompositeNode && string.IsNullOrEmpty(originalInsertNode.ToTxt().Trim()))
originalInsertNode.Remove();
}

Is there an easier and faster way to do that?

Hi Stanislav,

It is perfect that you managed to resolve the problem. I think you can simplify the code and avoid creating an intermediate document that you later insert into the bookmark. Since you are working within one document, you should not import nodes to another document. You should combine these methods to avoid creating an intermediate document.

Best regards,

Hi Alexey

I have very strange issue with a code that extracts bookmark content that i took from
http://www.aspose.com/documentation/.net-components/aspose.words-for-.net/howto-extract-selected-content-between-nodes-in-a-document.html

bookmarkStart = dstBookmark.BookmarkStart;
bookmarkEnd = dstBookmark.BookmarkEnd;

// Firstly extract the content between these nodes including the bookmark.
extractedNodes = ExtractContent(bookmarkStart, bookmarkEnd, false);

Document dstBookmarkContent = GenerateDocument(mDocument, extractedNodes);

I am extracting content from one bookmark and inserting it to another.
If i insert dstBookmarkContent to other bookmark in my document, it is or not inserted correctly or will throw error next time ill try to use this bookmark content.

If i am adding after GenerateDocument this code line:

dstBookmarkContent.Save(@“C:/Temp/temp3.doc”);

everything works fine. Do you know what could be a reason for this?

Hi Alexey,

This issue is very important for us. Can you please give me an answer as soon is possible.

Hi Stanislav,

Thanks for your request. You can try using code like the following to copy/move content between bookmarks:

[Test]

public void Test001()

{

Document doc = new Document(@"Test001\in.doc");

CopyBookmarkContent(doc.Range.Bookmarks["src"], doc.Range.Bookmarks["dst"], true);

doc.Save(@"Test001\out.doc");

}

///

/// Copies content from one bookmark to another.

///

/// Bookmark to copy from.

/// Bookmark to copy to.

/// Flag indicates whether we should copy or move content from source bookamrk to destination

private static void CopyBookmarkContent(Bookmark src, Bookmark dst, bool clearSrc)

{

// Nodes between which we need to copy content.

Node start = src.BookmarkStart;

Node end = src.BookmarkEnd;

Node insertAfter = dst.BookmarkStart;

// DocumentBuilder will help us to insert content into the destination bookmark.

DocumentBuilder builder = new DocumentBuilder((Document)src.BookmarkStart.Document);

builder.MoveToBookmark(dst.Name, true, true);

Node curNode = start.NextPreOrder(start.Document);

while (curNode != null && !curNode.Equals(end))

{

//Move to next node

Node nextNode = curNode.NextPreOrder(start.Document);

//Check whether current contains end node

if (curNode.IsComposite)

{

if (!((CompositeNode)curNode).GetChildNodes(NodeType.Any, true).Contains(end) &&

!((CompositeNode)curNode).GetChildNodes(NodeType.Any, true).Contains(start))

{

nextNode = curNode.NextSibling;

// If the current node is composite and the Documentbuidler cursor is in paragraph,

// where bookmark start is located, we should insert a paragraph break.

if (builder.CurrentParagraph.GetChildNodes(NodeType.Any, true).Contains(dst.BookmarkStart))

{

insertAfter = builder.CurrentParagraph;

builder.Writeln();

}

// If we need to copy content we should clone node if we should move just insert the original node.

Node nodeToInsert = clearSrc ? curNode : curNode.Clone(true);

insertAfter.ParentNode.InsertAfter(nodeToInsert, insertAfter);

// Insert after node should be also changed.

insertAfter = nodeToInsert;

}

}

else

{

builder.InsertNode(clearSrc ? curNode : curNode.Clone(true));

}

curNode = nextNode;

}

}

Hope this helps.

Best regards,