In my current project I’m working with Aspose.Words for .NET to create documents. Aspose.Words works very well for what I have to do. Though when it comes to debugging it starts being inefficient. It’s just a fact that a Word document has a fairly complex object model that has very deep object hierarchies with all its sections, headers, tables, paragraphs etc. This makes it cumbersome to navigate within the document and understand what the document you are inspecting really looks like in the debugger. Why?
The Visual Studio Debugger provides a couple of workflows to inspect our objects at runtime. Let’s try with these:
Looking at the different possibilities, like Object Tree, Watch Window and Immediate Window, Visual Studio offers us by default. It’s obvious that we will have a hard time finding the information we need about our document structure.
But Visual Studio is extensible and we can build our own debugger visualizer for Aspose.Words documents, don’t we?
So I started building a, until now, simple Aspose.Words Document Debugger Visualizer for Visual Studio 2012.
Let’s see what the Aspose.Words Document Debugger Visualizer can do at the moment. Hover over the Aspose.Words.Document object you like to examine and click the magnifying glass. At the moment it’s really very simple but it already displays the document structure in an XML format (image 5). Copy to clipboard or <ENTER> copies the complete text into the Clipboard, Close or <ESC> closes the visualizer screen. You cannot only inspect instances of Aspose.Words.Document but any object deriving from Aspose.Words.Node (e.g. Section, Paragraph etc.). This is because every element in the Aspose.Words.Document object model derives from Aspose.Words.Node.If you just like to use the Aspose.Words Document Debugger Visualizer. Go to my github repository, install it with the help of the Installation instructions and enjoy a better debugging experience for Aspose.Words.
Behind the Scenes
Continue reading if you are interested in knowing how the visualizer is implemented. I will not go into the details of how to build a debugger visualizer in general, this has to wait for another blog post. However I will explain the Aspose.Words related aspects. This knowledge can help you better understand some parts of Aspose.Words and work with it more efficiently.
Document Visitor
Every class derived from Aspose.Words.Node (Document, Section, etc) supports the concept of a DocumentVisitor. Simply create an instance of your visitor implementation and call the Aspose.Words.Node.Accept() method.
var visitor = new XmlStructureDocumentVisitor(); node.Accept(visitor);
This call visits the complete structure of the node object. If the node is a Document, it visits all sections and their underlying objects in the document, if it’s a Section it visits all paragraphs, headers etc. and their underlying objects in the section. And so on for whatever type of Node you execute Accept().
I will explain the concepts of the Aspose.Words.DocumentVisitor and use my XmlDocumentStructureVisitor as an example. It will simply build an XML document structure using a StringBuilder. You can have a look at the complete code in my github repository.
Every document visitor has to derive from Aspose.Words.DocumentVisitor:
using Aspose.Words; public class XmlStructureDocumentVisitor : DocumentVisitor {
DocumentVisitor is an abstract class providing empty virtual implementations for all methods so you only have to override the methods you like to. For most building blocks of a document (e.g. Document itself, Section, Paragraph etc.) there are specific VisitStart and VisitEnd methods.
public override VisitorAction VisitDocumentStart(Document doc) { this.structureBuilder.AppendLine("<Document>"); return VisitorAction.Continue; } public override VisitorAction VisitDocumentEnd(Document doc) { this.structureBuilder.AppendLine("</Document>"); return VisitorAction.Continue; } public override VisitorAction VisitParagraphStart(Paragraph paragraph) { this.IndentBy(3); this.structureBuilder .AppendFormat( "<Paragraph StyleIdentifier='{0}' StyleName='{1}'>", paragraph.ParagraphFormat.StyleIdentifier, paragraph.ParagraphFormat.StyleName) .AppendLine(); return VisitorAction.Continue; } public override VisitorAction VisitParagraphEnd(Paragraph paragraph) { this.IndentBy(3); this.structureBuilder.AppendLine("</Paragraph>"); return VisitorAction.Continue; } ...
some building blocks (e.g. Run, DrawingML, etc.) only have a single visit method.
public override VisitorAction VisitDrawingML(Aspose.Words.Drawing.DrawingML drawingMl) { this.structureBuilder.AppendLine("<DrawingML />"); return VisitorAction.Continue; } ... }
All visit methods have two things in common:
1. you get the currently visited object as parameter
2. you have to return a VisitorAction.
You get an editable reference to the currently visited object which means you can change everything on that object. Or just get information on that object as I do in the Debugger Visualizer.
The return value of every visit method is of type VisitorAction.
public enum VisitorAction { Continue, SkipThisNode, Stop, }
Usually you will return VisitorAction.Continue. Use VisitorAction.SkipThisNode if you don’t want to visit this node and its children. If you want to stop visiting of further nodes completely return VisitorAction.Stop.
This basically is the concept of the DocumentVisitor in Aspose.Words. There is an immense variety of scenarios where the DocumentVisitor can come in handy.
If you like to read about the visitor pattern have a look at the Wikipedia article.
In case you missed the link to the Aspose.Words Document Debugger Visualizer here it is once again.
RT @philippdolder: Just blogged: VS 2012 Debugger Visualizer for @aspose.Words: http://t.co/60mbB0LnFC
RT @planetgeekch: Just blogged: VS 2012 Debugger Visualizer for @aspose.Words: http://t.co/MCKyMV0WVZ
RT @planetgeekch: Just blogged: VS 2012 Debugger Visualizer for @aspose.Words: http://t.co/MCKyMV0WVZ
VS 2012 Debugger Visualizer for Aspose.Words: http://t.co/2zAnd2z22I
@planetgeekch created a VS 2013 Visual Studio Debugger for Aspose.Words for .NET to speed up your debugging. http://t.co/Uohi0x0BME
RT @aspose: @planetgeekch created a VS 2013 Visual Studio Debugger for Aspose.Words for .NET to speed up your debugging. http://t.co/Uohi0x…
@planetgeekch tells us about how his #Visual #Studio Debugger for #Aspose.#Words for .#NET speeds up #debugging. http://t.co/41FtoNnoSv