Introduction
The examples below assume aspose-note is installed; grab it from PyPI to follow along on your own notebook file:
pip install aspose-noteAspose.Note FOSS for Python exposes a full document object model — Document → Page → Outline → OutlineElement → RichText / Image / Table / AttachedFile — and gives you three
different ways to walk it. This guide covers each one: recursive type-filtered search
with GetChildNodes(), walking the hierarchy level by level yourself, and single-pass
traversal with a DocumentVisitor.
Recursive Search with GetChildNodes
GetChildNodes(Type) searches recursively from any node downward and returns each
descendant of the given type, regardless of how deep it’s nested. This is a direct way
to answer “find each RichText node in this notebook” without caring which page or
outline it belongs to:
from aspose.note import Document, RichText
doc = Document("notebook.one")
all_text = [rt.Text for rt in doc.GetChildNodes(RichText) if rt.Text]
Because the search is recursive, calling doc.GetChildNodes(RichText) finds text nested
inside tables and nested outlines too — you don’t need a separate call per container type.
Walking the Hierarchy by Hand
When you need to know which page or outline a node came from — not just that it exists
somewhere — walk the tree level by level instead of searching flat. Each level’s
GetChildNodes() call is scoped to its immediate parent:
from aspose.note import Document, Page, Outline, RichText
doc = Document("notebook.one")
for page in doc.GetChildNodes(Page):
title = "".join(page.Title.TitleText) if page.Title and page.Title.TitleText else "Untitled"
print(f"Page: {title}")
for outline in page.GetChildNodes(Outline):
for rt in outline.GetChildNodes(RichText):
text = "".join(rt)
if text.strip():
print(f" [{title}] {text[:80]}")
For deep-diving into what you can extract at each level — text runs, images, attachments, and tables — see Reading OneNote .one Files in Python with Aspose.Note FOSS.
Single-Pass Traversal with DocumentVisitor
DocumentVisitor is an abstract base class with VisitXStart/VisitXEnd hook pairs for
each node type (VisitDocumentStart, VisitPageStart, VisitTitleStart,
VisitOutlineStart, VisitOutlineElementStart, and their *End counterparts). Subclass
it, override the hooks you need, and pass an instance to Document.Accept() to drive one
traversal pass over the whole tree:
from aspose.note import Document, DocumentVisitor, Page
class TocVisitor(DocumentVisitor):
def __init__(self):
self.titles = []
def VisitPageStart(self, page: Page):
if page.Title and page.Title.TitleText:
self.titles.append("".join(page.Title.TitleText))
doc = Document("notebook.one")
toc = TocVisitor()
doc.Accept(toc)
print("\n".join(toc.titles))
Use a visitor instead of GetChildNodes() when you need to act on multiple node types in a
single pass, or when start/end pairs matter — for example, tracking how deeply nested an
outline element is by counting VisitOutlineStart/VisitOutlineEnd calls.
Outline Layout Properties
While traversing Outline nodes, you also get their layout coordinates —
HorizontalOffset, VerticalOffset, MaxWidth, MaxHeight, and MinWidth — which are
useful for layout-aware extraction or re-composition of a page:
from aspose.note import Document, Outline
doc = Document("notebook.one")
for outline in doc.GetChildNodes(Outline):
print(f"HOffset={outline.HorizontalOffset} VOffset={outline.VerticalOffset} MaxW={outline.MaxWidth}")
Which Approach to Use
GetChildNodes(Type)— you want each node of one type, anywhere in the tree, and don’t need to know its ancestors.- Manual hierarchy walk — you need parent context (which page, which outline) alongside each node.
DocumentVisitor— you need a single pass that reacts to several node types at once, or care about entering/leaving a container (start/end pairs).
For building a Document tree from scratch instead of reading one, see
Aspose.Note FOSS for Python — Key Features.