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

Free Support Forum - aspose.com

Determine if bookmark X is contained in bookmark T

My ultimate need is to determine if bookmark X is contained in bookmark T

For example, see bookmarks Table1, Table2 and Table3 in the attached sample.

The function would return TRUE for RR_DocMeetingAttendee_NameCompany and Table1, but false for Table2 and Table3.

I have had this function working for years in the MS word object model, and I thought I had a solution for Aspose.words - but this attached file thwarts it (yet works in the word code).

I have tried a document visitor, but when I do tableBookmark.bookmarkstart.accept(myVisitor)…it only visits a single node.

Any advice?

Note that I do not have much control over the word documents that I need to process.

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

Hi Stan,

Thanks for your inquiry.

Sure, please see the code examples below. You can take your choice, the first solution does not use DocumentVisitor, the second one does. Both should return the correct result.

bool containsBookmark1 = ContainsNestedBookmark(doc, "Table1","RR_DocMeetingAttendee_NameCompany");<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

bool containsBookmark2 = ContainsNestedBookmark(doc, "Table2", "Table3");

Without DocumentVisitor:

///

/// Returns true if the outer bookmark contains the inner bookmark.

///

public static bool ContainsNestedBookmark(Document doc, string outerBookmark, string innerBookmark)

{

Bookmark outer = doc.Range.Bookmarks[outerBookmark];

Bookmark inner = doc.Range.Bookmarks[innerBookmark];

NodeCollection allNodes = doc.GetChildNodes(NodeType.Any, true);

return allNodes.IndexOf(inner.BookmarkStart) > allNodes.IndexOf(outer.BookmarkStart) && allNodes.IndexOf(inner.BookmarkEnd) < allNodes.IndexOf(outer.BookmarkEnd);

}

With DocumentVisitor:

///

/// Returns true if the outer bookmark contains the inner bookmark.

///

public static bool ContainsNestedBookmark(Document doc, string outerBookmark, string innerBookmark)

{

return !doc.Accept(new BookmarkChecker(doc.Range.Bookmarks[outerBookmark], doc.Range.Bookmarks[innerBookmark]));

}

///

/// Checks if the outer bookmark contains the inner bookmark and stops (returns false). Otherwise continues until the

/// end of the document and returns true.

///

public class BookmarkChecker : DocumentVisitor

{

private Bookmark mOuterBookmark;

private Bookmark mInnerBookmark;

private bool isInOuter;

private bool containsInnerStart;

public BookmarkChecker(Bookmark outer, Bookmark inner)

{

mOuterBookmark = outer;

mInnerBookmark = inner;

}

public override VisitorAction VisitBookmarkStart(BookmarkStart bookmarkStart)

{

if (bookmarkStart == mOuterBookmark.BookmarkStart)

isInOuter = true;

if (isInOuter && bookmarkStart == mInnerBookmark.BookmarkStart)

containsInnerStart = true;

return VisitorAction.Continue;

}

public override VisitorAction VisitBookmarkEnd(BookmarkEnd bookmarkEnd)

{

if (bookmarkEnd == mInnerBookmark.BookmarkEnd && containsInnerStart && isInOuter)

return VisitorAction.Stop;

if (bookmarkEnd == mOuterBookmark.BookmarkEnd)

isInOuter = false;

return VisitorAction.Continue;

}

}

Thanks,

Thanks for the quick and thorough response!


I went with the AllNodes solution – looks like less overhead, but probably doc.GetChildNodes(,deep) does something similar to the visitor to collect the nodes. Anyhow, the solution is working perfectly.

One parting comment: if only the BookMark object had a RANGE property instead of its alternative text property….then

not outerBookmark.range.bookmarks(innerName) is nothing

would do the trick...

Hi Stan,

Thanks for your inquiry.

Sure, I have logged your request for such a feature. We will inform you through a post of this thread as soon as there are any developments.

Thanks,

An update on this - I have seem several times when Aspose seems to reverse the order of the two BookmarkStart nodes.

This happens if and only if there is text in the table and the Outerbookmark is outside the table and the inner bookmark is inside the first cell *before* the text....and then only if edited with Word - so word is somehow involved.

The attached file returns 92 for the BookmarkStart index of bookmark Table1 (which contains the entire table) and 91 for the BookmarkStart index of bookmark RR_DocRoute_NameCo (which is inside the first cell)

This isn't terribly urgent, because this workaround seems to do the trick by tollerating the startnodes being adjacent and in either order.

Return allNodes.IndexOf(inner.BookmarkStart) >= (allNodes.IndexOf(outer.BookmarkStart) - 1) _

AndAlso allNodes.IndexOf(inner.BookmarkEnd) < allNodes.IndexOf(outer.BookmarkEnd)

Hi

Thank you for additional information. Actually Aspose.Words returns correct order of bookmarks in this case. If you open XML of your document, you will see that BookmarkStart of Table1 follows BookmarkStart of RR_DocRoute_NameCo. Please see the attached screenshot.

Best regards,