OneNote Schema Overview

Microsoft Corporation

Summary: The new OneNote 1.1 Type Library includes functionality which enables you to programmatically import images, ink, and HTML into OneNote.

Contents

Introduction

Using the CSimpleImporterClass

Conclusion

Introduction

For Service Pack 1 (SP1) , Microsoft® Office OneNote™ 2003 adds extensibility functionality that enables applications to interoperate with it in an important, fundamental way— they can add content to OneNote notebooks. You can now push content to OneNote that includes html, images, and ink (such as from a Tablet PC). You can even create the folder, section, or page onto which you want to place your content.

Note   These extensibility features are only available in the OneNote 2003 Service Pack 1. Download a copy of OneNote 2003 Service Pack 1 from Office Online.

Using the CSimpleImporterClass

OneNote SP1 exposes a single class, CSimpleImporterClass, which enables you to add content to an OneNote notebook programmatically. You can add text in html form, images, and even ink from a Tablet PC. The CSimpleImporterClass enables you to specify where in the notebook you want to place the content; you can even create folders, sections, and pages for content, and then programmatically display the desired page. The import functionality of OneNote also lets you later delete the content you import.

The CSimpleImporterClass consists of two methods:

To use the CSimpleImportClass, you must add a reference to the OneNote 1.1 Type Library to your project. To add a reference, in Visual Studio .NET, on the Solution Explorer window, right-click References and then click Add Reference. On the COM tab, select OneNote 1.1 Type Library in the list, click Select, and then click OK.

While this article focuses on implementing the import functionality in OneNote using .NET-based languages, you can also use the OneNote 1.1 Type Library with unmanaged code, such as Microsoft Visual Basic® 6.0 or Microsoft Visual C++® development system.

The Data Import Schema

The Import method has the following signature:

Import (bstrXml as String)

The method takes an xml string describing the content object(s) you want to import, as well as the location in the notebook where you want them placed. You can also use the Import method to delete objects you have previously placed in the notebook.

When called, OneNote executes the Import method with minimal intrusion on the user. OneNote does open if it is not already opened, which means the OneNote splash screen displays. But it does not change the user's location in the notebook if OneNote is already running. To change the focus of the OneNote application to the new content, use the NavigateToPage method, discussed later in this article.

If the Import method fails, OneNote does not display an error to the user. However, the COM interface does return one of the following errors to the application making the call:

Error Name Error Type
MALFORMED_XML_ERROR 0x80041000
INVALID_XML_ERROR0x80041001
ERROR_CREATING_SECTION0x80041002
ERROR_OPENING_SECTION0x80041003
SECTION_DOES_NOT_EXIST_ERROR0x80041004
PAGE_DOES_NOT_EXIST_ERROR0x80041005
FILE_DOES_NOT_EXIST_ERROR0x80041006
ERROR_INSERTING_IMAGE0x80041007
ERROR_INSERTING_INK0x80041008
ERROR_INSERTING_HTML0x80041009
ERROR_NAVIGATING_TO_PAGE 0x8004100a

OneNote parses the XML file in a linear manner. If OneNote encounters an error, it terminates the import and does not process any subsequent content in the file. Any previous, successful imports from the file are not rolled back. For example, suppose you generated an XML file that contained two <EnsurePage> elements and two <PlaceObjects> elements. Unfortunately, the first PlaceObjects element passes a non-existent GUID as its pageGUID attribute. In this case, OneNote retains any folders, sections, and pages created through the <EnsurePage> elements. The first <PlaceObjects> element fails, and once it does, OneNote terminates the import and doesn't read the rest of the file, whether or not the second <PlaceObjects> element is correctly constructed.

The following figures outline the xml schema to which the import file must adhere.

Outline of the Import root element structure.

Figure 1. XML Schema Structure of the Import Root Element

Outline of the PlaceObjects element.

Figure 2. Schema Structure of the PlaceObjects Element

Note   The namespace for the Import method is different in the release version of OneNote 2003 SP1 than the namespace for the SP1 preview.

The namespace for the OneNote SP1 Preview is:

http://schemas.microsoft.com/office/onenote/01/2004/import

While the namespace for OneNote SP1(release version) is:

http://schemas.microsoft.com/office/onenote/2004/import

If you created an application to work with OneNote SP1 Preview, you must update that application with the new namespace for it to function properly with OneNote 2003 SP1.

There are two elements directly below the root <Import> element. Use the first element, <EnsurePage>, to make sure the folder, section, and page on which you want to place content exists. Use the second element, <PlaceObjects>, to place or delete objects from the page. The schema requires that the root element contain either at least one <EnsurePage> or <PlaceObjects> element.

Creating Folders and Pages for Content

Before you import content, the target pages for that content must exist in the OneNote notebook. Use the <EnsurePage> element to verify or create the target pages for your content. For each page you specify in an <EnsurePage> element, OneNote checks to determine if the page exists, and if not, creates it. You can even create notebook folders and sections by specifying folders or sections that don't exist.

You are required to pass OneNote a string representing the path to the desired page, as well as a GUID for that page. If the path is not fully-qualified, OneNote assumes the string starts from the notebook root location for the user. Additionally, you can specify the title, date, reading direction, and page placement relative to other pages in the notebook.

Note All GUIDs passed to OneNote methods must be in registry format, which includes being surrounded by curly braces ({}).

By default, OneNote inserts each new page at the end of the specified section. If you specify a page GUID for the insertAfter attribute, OneNote inserts the new page as a sub-page of the page whose GUID you specified. In such cases, the sub-page shares the title and date with the other pages in the page series. If the page you specify does not exist (for example, if it was never added, or the user deleted it), then OneNote inserts the new page at the end of the specified section, with any specified title and date values.

Consider the following example. This <EnsurePage> element specifies a page in the OneNote section title Negotiations, in the folder Johnson Contract, in the user's root notebook folder. The page is titled "Budget Concerns".

<EnsurePage path="Johnson Contract\Negotiations.one"
            guid="{8FDD3C41-5BB5-4595-B019-7E7E9BC9D38E}" 
            title="Budget Concerns"/>

OneNote uses the optional attributes of the <EnsurePage> element when it creates a new page. If you specify attributes for an existing page, OneNote leaves the page attributes unchanged. For example, if you use a GUID for an existing page, and specify a title that differs from that page's current title, OneNote does not change the page title.

Additionally, OneNote only searches the path you specify for the desired page GUID. If the page GUID does not exist in the specified section, OneNote creates it; it does not look for the GUID in other sections of the notebook.

You can use multiple <EnsurePage> elements to create multiple pages within the OneNote notebook. You are not required to include an <EnsurePage> element for each page on which you want to place content. However, if you use the <PlaceObjects> element to try and place objects on a page that does not exist, the Import method fails. In some cases, this may be the desired outcome; for example, if you only wanted to update content on a page if the page still exists, and not add the content if the page has been deleted by the user.

Placing Content on Pages

Once you ensure that the pages onto which you want to import data exist in the OneNote notebook, you can start placing objects on them using the <PlaceObjects> element. You can import multiple objects to multiple pages if desired. You create a <PlaceObjects> element for each page on which you want to place content. Same as the <EnsurePage> element, <PlaceObjects> has two required attributes: the path to the page, and the GUID assigned to the page. You must include at least one <Object> element in each <PlaceObjects> element.

To create the xml string that describes the content you want to import into OneNote, follow these general steps:

Some other technical requirements to remember as you create the xml string:

Updating Content

To update objects that are already in a notebook, simply re-import the objects to the same page, using the same GUIDs. Be aware, however, that re-importing an object overwrites that object without notifying the user. Any changes made to the content since it was last imported are lost.

Deleting Content

To delete an object, place the <Delete/> element within the object element. To delete an object, you must be able to identify it by its GUID and path. In practical terms, this generally means an application can only delete objects it places in OneNote to begin with. However, if the application stores the GUID across sessions, it can delete objects it imported into OneNote in previous sessions. You cannot delete folders, sections, or pages, even those you created.

Sample XML String

Below is an example of what a typical xml string for the Import method might resemble. This xml file describes the placement of three new objects onto an existing page, and the deletion of an object already contained on that page.

<?xml version="1.0"?>
<Import xmlns="http://schemas.microsoft.com/office/onenote/2004/import">

  <EnsurePage path="MSN Instant Messenger\Conversations.one"
              guid="{8FDD3C41-5BB5-4595-B019-7E7E9BC9D38E}" 
              title="Personal" 
              date="2003-10-16T17:30:00-08:00"
              insertAfter="{05239BEA-894E-406d-80AD-8678D1BC1EDD}"/>

  <PlaceObjects pagePath="MSN Instant Messenger\Conversations.one" 
                pageGuid="{8FDD3C41-5BB5-4595-B019-7E7E9BC9D38E}">

    <Object guid="{5FCFD7F9-02C2-42fc-B6AF-7A8450D43C2D}">
      <Position x="72" y="72"/>
      <Image backgroundImage="true">
      <File path="c:\image.png"/>
      </Image>
    </Object>

    <Object guid="{F6FC4149-1092-48ea-806D-0067C8661A18}">
      <Position x="72" y="72"/>
      <Ink>
        <File path="c:\ink.isf"/>
      </Ink>
    </Object>

    <Object guid="{7EA551C4-F778-40ce-9181-21A3DB6D33CA}">
      <Position x="72" y="432"/>
      <Outline width="360">
        <Html>
          <Data>
            <![CDATA[
              <html><body><p>Sample text here.</p></body></html>
              ]]>
          </Data>
    </Html>
    </Outline>
    </Object>

    <Object guid="{1A6648BA-D792-48f1-AC6A-43DF6E258851}">
   <Delete/>
  </Object>

  </PlaceObjects>

</Import>

The following example demonstrates a basic implementation of the OneNote import functionality. The code displays a dialog that enables the user to select an xml file, and then passes the contents of that xml file as an argument for the Import method. This example assumes the xml file conforms to the OneNote data import schema. This example also assumes the project contains a reference to the OneNote 1.0 Type Library.

Dim strFileName As String
Dim XmlFileStream As StreamReader
Dim strImportXml As String
Dim objOneNote As OneNote.CSimpleImporterClass

OpenFileDialog1.Filter = "XML files (*.XML)|*.XML|Text files (*.TXT)|*.TXT"
OpenFileDialog1.ShowDialog()
strFileName = OpenFileDialog1.FileName()

objOneNote = New OneNote.CSimpleImporterClass
XmlFileStream = New StreamReader(strFileName)
strImportXml = XmlFileStream.ReadToEnd
objOneNote.Import(strImportXml)

XmlFileStream.Close()

For the sake of simplicity, so as to highlight how the Import method is implemented, the following example assumes that an XML file is already created to use as the string for the Import method. In most cases, however, the application that calls the Import method first creates the XML string itself. For more information on creating XML using the .NET framework, see Well-Formed XML Creation with the XMLTextWriter.

In addition, most applications need to create and assign GUIDs to the pages and objects they create. Use the NewGuid method to create a new GUID, and the ToString method to get the string representation of the value of GUID, which the XML string requires. For more information, see GUID Structure in the .NET Framework Class Library.

The following example demonstrates how you can programmatically generate xml strings and object GUIDs for use with the OneNote import functionality. In this sample, the user specifies a location, and optionally, a title, for a new page that the application then creates using the CSimpleImporterClass.Import method.

Sample Application Interface

Figure 3. Sample Application Interface

Once the sample has stored the user input in two variables, it calls the NewGuid method to generate a new GUID for the page to create. Note that because the NewGuid method is a shared method, you do not have to instantiate a Guid object in order to call it. OneNote only accepts GUIDs in registry format, which includes curly braces ({}). However, the NewGuid method does not generate GUIDs in registry format. In order for OneNote to correctly process it, you must first wrap the generated GUID in curly braces.

The sample then constructs the simple xml document required for the Import method. The code employs an XMLTextWriter object and its various methods to generate an xml stream. The code creates <Import> and <EnsurePage> elements and their required attributes. If the user specifies a page title, the code creates the optional title attribute of the <EnsurePage> element as well. Once it has created the xml stream, it flushes the XmlTextWriter object and moves the position back to the beginning of the stream.

At this point, the code uses a StreamReader object to write the contents of the xml stream to the console, to demonstrate what the xml generated looks like. Because the Import method takes a string, not a stream, the code uses the StreamReader.ReadToEnd method to get a string representing the contents of the xml stream. The code then passes this string as the required argument to the Import method, thereby creating the desired page. Finally, the code calls the NavigateToPage method, and passes it the page path and page GUID variables set earlier, in order to navigate to the new page in OneNote.

Imports System.Xml
Imports System.IO
...
    Private Sub btnCreate_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles btnCreate.Click
        Dim pagePath As String
        Dim pageTitle As String
        Dim pageGuid As String
        Dim XmlImportStream As MemoryStream = New MemoryStream
        Dim XmlImportWriter As XmlTextWriter = _
            New XmlTextWriter(XmlImportStream, Nothing)
        Dim strEnsurePage As String
        Dim OneNoteImporter As OneNote.CSimpleImporterClass

        'store user input for path and optional page title
        pagePath = Me.txtPagePath.Text.ToString
        pageTitle = Me.txtPageTitle.Text.ToString
        'generate a new GUID for the page to be created
        pageGuid = "{" & Guid.NewGuid.ToString & "}"

        'Generate the xml as a stream
        With XmlImportWriter
            .WriteStartDocument()
            'Generate root Import element
            'and specify OneNote schema namespace
            .WriteStartElement("Import")
            .WriteAttributeString("xmlns", _
                "http://schemas.microsoft.com/office/onenote/01/2004/import")
            .WriteStartElement("EnsurePage")
            'Generate required path attribute
            .WriteAttributeString("path", pagePath)
            'Generate required GUID attribute
            .WriteAttributeString("guid", pageGuid)
            'Generate opotional title attribute, if title was specified
            If Not pageTitle = "" Then
                .WriteAttributeString("title", pageTitle)
            End If
            .WriteEndElement()
            .WriteEndElement()
            .WriteEndDocument()
        End With
        'Flush the xmltextwriter
        XmlImportWriter.Flush()
        'Move to the start of the xml stream
        XmlImportStream.Position = 0
        'Create a streamreader for the xml stream
        Dim XmlImportReader As StreamReader = New StreamReader(XmlImportStream)
        'Write the xml stream to the console
        Console.WriteLine(XmlImportReader.ReadToEnd)
        Console.ReadLine()
        'Move back to the start of the xml stream
        XmlImportStream.Position = 0
        'Store entire xml stream in variable as a string
        strEnsurePage = XmlImportReader.ReadToEnd
        'Create instance of OneNote simple importer
        OneNoteImporter = New OneNote.CSimpleImporterClass
        'Pass xml string to import method to create page
        OneNoteImporter.Import(strEnsurePage)
        'Navigate to new page, based on path and GUID variables
        OneNoteImporter.NavigateToPage(pagePath, pageGuid)

    End Sub

Displaying a Specified Page

By design, when the Import method executes the user is not distracted by OneNote displaying data they may not want to see, or worse, navigated away from the OneNote page currently in use. Also, in the cases where you import multiple objects to multiple pages, OneNote does not have to make assumptions about which page the user wants to see, if any.

To display a specific page, use the NavigateToPage method. If OneNote is not open, this method opens OneNote to the specified page. If OneNote is already open, the method navigates to the specified page in the current instance of OneNote.

To select the page to display, you must specify the path to the page, as well as the GUID for that page. If you specify a page that does not exist, OneNote returns an error.

The NavigateToPage method has the following signature:

NavigateToPage(bstrPath as String, bstrGuid as string)

Conclusion

The new import functionality in OneNote opens up exciting possibilities for interacting with other applications. Any application that can save data (either its own or another application's) as html text, images, or ISF can now push that content into OneNote and place it wherever you want. And as long as the application retains the GUIDs used, it can update or delete the content it pushed whenever necessary.

©2003-2004 Microsoft Corporation. All rights reserved. Permission to copy, display and distribute this document is available at: http://msdn.microsoft.com/library/en-us/odcXMLRef/html/odcXMLRefLegalNotice.asp