OneNote: An In-Depth Look at the OneNoteImporter Managed Assembly (Part 3 of 5)
In this series of entries, we're taking an in-depth at the OneNoteImporter manage class, which provides an object model interface for the programmability functionality added in OneNote 2003 SP 1.
Importing Objects into OneNote
The actual creation of the XML import document, and importing the page contents, takes place when you call the Page.Commit method. This method, in turn, invokes a number of methods in other OneNoteImporter objects. Because of this method’s importance and complexity, it’s worth examining how the method functions.
First, the code checks to see if the page has changed in any way from the last time it was imported. It does this by determining if the Page object’s CommitPending property is set to True. If it is, it calls the SimpleImporter.Import method.
The code calls the Page.ToString method to generate the XML string it passes to the Import method. The ToString method in turn calls the Page.SerializeToXml method.
This begins a series of recursive calls to the SerializeToXml methods of the various objects. Each object’s SerializeToXml method includes instructions to call the SerializeToXml method of any child objects, and append the resulting XML to the parent element. This in turn invokes the SerializeToXml method of any child objects the original child object might have, and so on, until the entire page structure has been serialized to xml in a single xml document.
The Page.SerializeToXml begins by creating a new XmlDocument object, and generating <Import> and <EnsurePage> elements and adding them to the document. Page object property values are used to set the various attributes of the <EnsurePage> element.
Note that the Commit method generates import XML with both <EnsurePage> and <PlaceObjects> elements for that page. Specifying an <EnsurePage> element for a page guarantees that the page exists before OneNote attempts to import objects onto it. So if your application includes a scenario where you only want to import objects onto a page if the page already exists, you’ll need to modify this method, or use another means.
The code then generates a <PlaceObjects> element. For each of the Page object’s children whose CommitPending property is set to True, the code calls the PageObject.SerializeToXml method.
If the page object’s DeletePending property is set to True, the PageObject.SerializeToXml method generates a <Delete> element. If not, the method does three things:
· Generates a <Position> element, whose attributes are set according to Position object property values.
· Calls the SerializeObjectToXml method for the specific PageObject-derived class involved, i.e., ImageObject, InkObject, or OutlineObject.
· Calls the SerializeToXml method for the specific OutlineContent-derived class involved, i.e., HtmlContent, InkContent, or ImageContent.
Executing the SerializeToXml method for each of these content types includes a call to the SerializeToXml method for the Data-derived object they contain: BinaryData, FileData, or StringData. In this way, the entire page structure is serialized to xml in a single xml document.
Note that the HtmlContent.SerializeToXml method includes a call to another internal method of that same object, called CleanHtml. The CleanHtml method reads through the html string or file data and makes sure the HTML is formatted in a way that OneNote accepts. It identifies and replaces problematic formatting with characters which OneNote can process. For example, the CleanHtml method wraps the HTML string with the appropriate <html> and <body> tags if the HTML lacks them.
The serialization of the page nodes is now complete. If the Page object had no children, the <PlaceObjects> element remains empty. In such a case, the Page.SerializeToXml method does not append it to the <Import> element.
Finally, the Page.SerializeToXml method determines the appropriate namespace designation and adds it to the <Import> element.
The ToString method then takes the XmlDocument object, saves it as a text stream, converts it to a string, and passes it back to the SimpleImporter.Import method. This Import method uses the XML string to import the specified content into OneNote.
Now that the content has been imported into OneNote, the Commit method performs some vital housekeeping. Using the RemoveChild method, it removes any of the Page object’s children who have their DeletePending property set to True. It then sets the private committed field to True, thereby making the Date, PreviousPage, RTL, and Title propertiesread-only. You cannot change these attributes once you import a page into OneNote.
Lastly, it sets the CommitPending property of the Page to False. This it turn sets the CommitPending properties of all the Page object’s remaining children to False as well.
In part four, we'll examine the internal method calls of the Commit method.