I have a table, each row in a table is a book mark and each cell within the row is another book mark.
When I parse the book marks, Row2 book mark starts and then the row1 book mark ends,
Attached is the file.
Thank you
I have a table, each row in a table is a book mark and each cell within the row is another book mark.
When I parse the book marks, Row2 book mark starts and then the row1 book mark ends,
Attached is the file.
Thank you
Yes, that is normal. Aspose.Words model just reflects the order in which the bookmarks are stored in the document by MS Word. Of course, that can cause some difficulties when you need to rely on bookmarks during document processing. If you need to solve some particular task by parsing the bookmarks, then please describe this task to me, maybe I will be able to help you to find a better solution or a workaround.
Best regards,
Vladimir, Thank you for your response.
My situation is that based on my data I may need to delete the book mark row 2. but when I do that it takes with it the ending tag of book mark row 1.
so now my book mark row 1 has no ending tag.
Sharad
If your task is to delete bookmarked rows, then to prevent bookmark overlapping it is better not to bookmark the entire row, but put an empty bookmark somewhere inside it.
Aspose.Words API will let you to define the row which contain the specified bookmark and you can remove it then.
To illustrate the point here is a sample code (that uses one of the cell bookmarks in your sample document):
Row row = (Row)doc.Range.Bookmarks[“r1c1”].BookmarkStart.GetAncestor(typeof(Aspose.Words.Row));
row.Remove();
Please also note that if you remove one of bookmark nodes (start or end) the other is removed automatically by Aspose.Words to maintain the document integrity.
Hope this helps,
This is a conversion project that I am working on, There are more then 400 templets and files are more then 2MB each, its not possible to modify the file.
Is there any other way out?
Sharad
I have logged this problem to our defect base as issue #1352. We will try to fix it as soon as possible.
For temporary workaround you can use cell bookmarks to remove rows as shown in my previous post.
Best regards,
The thing is bookmarks are zero-length objects in a Word document and there could be several bookmark starts/ends in a same character position. This is the case with your bookmarks.
If we look at this file in WordML, we can see two bookmarks start and one bookmark ends all in the same position and Microsoft Word tends to “twist” and put bookmark ends after bookmark starts in such case.
<aml:annotation aml:id="4" w:type="Word.Bookmark.Start" w:name="ROW2" />
<aml:annotation aml:id="5" w:type="Word.Bookmark.Start" w:name="r2c1" />
<aml:annotation aml:id="0" w:type="Word.Bookmark.End" />
When Aspose.Words reads such document, it has to represent all of that in a tree of nodes and the order of the bookmark nodes becomes important.
If you had two bookmarks starting and ending in normal text, then Aspose.Words will automatically “untwist” the bookmarks in the tree so the bookmarks. That is a bookmark will end before the other bookmark starts. But this does not work for rows yet and I’m not sure I can easily do that.
You best option will be to proceed and code around this. For example, you can code to move the BookmarkEnd node that you don’t want to delete to the last cell of the previous row.
Thanks, Roman,
Can you send me some sample code to move the Bookmarks around, I get the followign error when I try to insert the node in a different place.
java.lang.UnsupportedOperationException: Adding nodes is not yet supported for deep node collections.
at com.aspose.words.NodeCollection.add(Unknown Source)
at test.AsposeModel.cleanEmbeddedBookmarks(AsposeModel.java:245)
at test.AsposeModel.main(AsposeModel.java:35)
Thank you,
Sharad
Please provide the code snippet and the document template that will allow us to reproduce this error. Also, to find a workaround we need to know more about what your task in this case is and what you are trying to achieve when using the code that causes the error.
Best regards,
Miklovan,
Attached is a document and the code.
the output is
0 Section
1 BODY
2 Paragraph
3 Run
4 Paragraph
5 Run
6 Paragraph
7 Paragraph
8 Table
9 Row
10 Cell
11 Paragraph
12 ROW1 = BOOKMARK_Start
13 r1c1 = BOOKMARK_Start
14 Run
15 r1c1 = BOOKMARK_END
16 Cell
17 Paragraph
18 Run
19 Cell
20 Paragraph
21 r1c3 = BOOKMARK_Start
22 Run
23 r1c3 = BOOKMARK_END
24 Row
25 Cell
26 Paragraph
27 ROW1 = BOOKMARK_END
28 ROW2 = BOOKMARK_Start
29 Run
30 r2c1 = BOOKMARK_Start
31 Run
32 r2c1 = BOOKMARK_END
33 Cell
34 Paragraph
35 Run
36 Cell
37 Paragraph
38 Run
39 Row
40 Cell
41 Paragraph
42 ROW3 = BOOKMARK_Start
43 ROW2 = BOOKMARK_END
44 r3c1 = BOOKMARK_Start
45 Run
46 r3c1 = BOOKMARK_END
47 Cell
48 Paragraph
49 Run
50 Cell
51 Paragraph
52 Run
53 Paragraph
54 ROW3 = BOOKMARK_END
//////////////////////////////////////////////////
I want to move the book mark
43 ROW2 = BOOKMARK_END
to between 36 Cell and 39 Row
The document
Here is the code in C# that does what you are trying to achieve. I have tested it on the document that you have attached and it works fine.
BookmarkEnd bookmarkEnd = doc.Range.Bookmarks["Row2"].BookmarkEnd;
// BookmarkEnd currently belongs to first paragraph of the row.
// We want to move it to the end of the last paragraph of the previous row.
// For this let’s search for the paragraph preceding the paragraph the BookmarkEnd
// currently belongs to, using tree-traversal.
Node node = bookmarkEnd.ParentNode.PreviousPreOrder(doc);
while (node.NodeType != NodeType.Paragraph)
{
node = node.PreviousPreOrder(doc);
}
Paragraph newParent = (Paragraph)node;
// Remove BookmarkEnd from the old position in the beginning of the row.
bookmarkEnd.Remove();
// Add BookmarkEnd to a new position in the end of previous row.
newParent.AppendChild(bookmarkEnd);
Please let me know if you need help converting it to Java.
Best regards,
Roman, here is a note from a discussion thread.
The problem is we have 3+ bookmarks starting or ending at the same spot in a row and they really get mixed up.
So when a document with row bookmarks is loaded into Aspose.Words it looks like this:
As you can see the end of the ROW1 bookmark is in the second row.
I agree it would be nice if the end of the ROW1 bookmark was at the end of the first row. But unfortunately I cannot see a good way of changing this (you can say this is the way it is stored in MS Word, you can actually see the same order in WordML and in RTF if you save this file from MS Word). So at this stage we are not going to change this behaviour in Aspose.Words.
But I created a simple project that untangles such bookmarks. You can execute this code to untangle row bookmarks after you load the document and before you start deleting rows.
Here is how the untangled bookmark looks like (and second row is deleted without affecting the bookmark for the first row):
Attached is the complete project with a sample document. Sorry it is in C#. Let me know if you have problem writing this in Java.
Here is the source code:
using System;
using System.IO;
using System.Reflection;
using Aspose.Words;
namespace Project
{
class Demo
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)
{
Demo demo = new Demo();
demo.Execute();
}
private string TemplateDir
{
get
{
// The templates are stored in the directory one level up from the bin directory.
return Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
}
}
private void Execute()
{
// Load the template document.
Document doc = new Document(Path.Combine(TemplateDir, "TestDefect1352.doc"));
// This perform the cusom task of putting the row bookmark ends into the same row with the bookmark starts.
UntangleRowBookmarks(doc);
// Now we can easily delete rows by a bookmark without damaging other rows bookmarks.
DeleteRowByBookmark(doc, "ROW2");
// This is just to check that the other bookmark was not damaged.
if (doc.Range.Bookmarks["ROW1"].BookmarkEnd == null)
throw new Exception("Wrong, the end of the bookmark was deleted.");
// Save the finished document.
doc.Save(Path.Combine(TemplateDir, "TestDefect1352 Out.doc"));
}
private void UntangleRowBookmarks(Document doc)
{
foreach (Bookmark bookmark in doc.Range.Bookmarks)
{
// Get the parent row of both the bookmark and bookmark end node.
Row row1 = bookmark.BookmarkStart.GetAncestor(typeof(Row)) as Row;
Row row2 = bookmark.BookmarkEnd.GetAncestor(typeof(Row)) as Row;
// If both rows are found okay and the bookmark start and end are contained
// in adjacent rows, then just move the bookmark end node to the end
// of the last paragraph in the last cell of the top row.
if ((row1 != null) && (row2 != null) && (row1.NextSibling == row2))
row1.LastCell.LastParagraph.AppendChild(bookmark.BookmarkEnd);
}
}
private void DeleteRowByBookmark(Document doc, string bookmarkName)
{
// Find the bookmark in the document. Exit if cannot find it.
Bookmark bookmark = doc.Range.Bookmarks[bookmarkName];
if (bookmark == null)
return;
// Get the parent row of the bookmark. Exit if the bookmark is not in a row.
Row row = bookmark.BookmarkStart.GetAncestor(typeof(Row)) as Row;
if (row == null)
return;
// Remove the row.
row.Remove();
}
}
}
There is a new code example in wiki that deals with the bookmark removal:
https://docs.aspose.com/words/net/working-with-bookmarks/
Please try it an let me know if it solves your problem.