Hoe de OneNote Document DOM te doorlopen in Python

Hoe de OneNote Document DOM te doorlopen in Python

Aspose.Note FOSS for Python represents a OneNote section file as a tree of typed Python objects. Understanding how to traverse this tree efficiently is the foundation for all content extraction tasks. This guide covers all three traversal approaches: GetChildNodes, directe iteratie, en DocumentVisitor.


Het Document Object Model

De OneNote DOM is een strikte boom:

Document
  ├── Page
  │     ├── Title
  │     │     ├── TitleText (RichText)
  │     │     ├── TitleDate (RichText)
  │     │     └── TitleTime (RichText)
  │     └── Outline
  │           └── OutlineElement
  │                 ├── RichText
  │                 ├── Image
  │                 ├── AttachedFile
  │                 └── Table
  │                       └── TableRow
  │                             └── TableCell
  │                                   └── RichText / Image
  └── Page  (next page ...)

Elke knoop erft van Node. Knooppunten die kinderen hebben, erven van CompositeNode.


Methode 1: GetChildNodes (Recursief, Type‑gefilterd)

CompositeNode.GetChildNodes(Type) voert een recursieve depth-first zoekopdracht uit op de volledige subboom en retourneert een platte lijst van alle knopen die overeenkomen met het opgegeven type. Dit is de meest handige aanpak voor inhoudsextractie:

from aspose.note import Document, RichText, Image, Table, AttachedFile

doc = Document("MyNotes.one")

##All RichText nodes anywhere in the document
texts = doc.GetChildNodes(RichText)
print(f"RichText nodes: {len(texts)}")

##All images
images = doc.GetChildNodes(Image)
print(f"Image nodes: {len(images)}")

##All tables
tables = doc.GetChildNodes(Table)
print(f"Table nodes: {len(tables)}")

##All attachments
attachments = doc.GetChildNodes(AttachedFile)
print(f"AttachedFile nodes: {len(attachments)}")

Beperk de zoekopdracht tot één pagina door aan te roepen GetChildNodes op Page in plaats van Document:

from aspose.note import Document, Page, RichText

doc = Document("MyNotes.one")
for page in doc.GetChildNodes(Page):
    page_texts = page.GetChildNodes(RichText)
    print(f"  Page has {len(page_texts)} text nodes")

Methode 2: Directe kinditeratie

for child in node itereert de directe kinderen van een CompositeNode. Gebruik dit wanneer je één specifiek niveau van de hiërarchie nodig hebt:

from aspose.note import Document

doc = Document("MyNotes.one")

##Direct children of Document are Pages
for page in doc:
    title = (
        page.Title.TitleText.Text
        if page.Title and page.Title.TitleText
        else "(untitled)"
    )
    print(f"Page: {title}")
    # Direct children of Page are Outlines (and optionally Title)
    for child in page:
        print(f"  {type(child).__name__}")

Methode 3: DocumentVisitor

DocumentVisitor biedt een visitor‑patroon voor gestructureerde traversie. Overschrijf alleen de VisitXxxStart/End methoden die je nodig hebt. De visitor wordt aangeroepen door doc.Accept(visitor):

from aspose.note import (
    Document, DocumentVisitor, Page, Title,
    Outline, OutlineElement, RichText, Image,
)

class StructurePrinter(DocumentVisitor):
    def __init__(self):
        self._depth = 0

    def _indent(self):
        return "  " * self._depth

    def VisitPageStart(self, page: Page) -> None:
        t = page.Title.TitleText.Text if page.Title and page.Title.TitleText else "(untitled)"
        print(f"{self._indent()}Page: {t!r}")
        self._depth += 1

    def VisitPageEnd(self, page: Page) -> None:
        self._depth -= 1

    def VisitOutlineStart(self, outline) -> None:
        self._depth += 1

    def VisitOutlineEnd(self, outline) -> None:
        self._depth -= 1

    def VisitRichTextStart(self, rt: RichText) -> None:
        if rt.Text.strip():
            print(f"{self._indent()}Text: {rt.Text.strip()!r}")

    def VisitImageStart(self, img: Image) -> None:
        print(f"{self._indent()}Image: {img.FileName!r} ({img.Width}x{img.Height}pts)")

doc = Document("MyNotes.one")
doc.Accept(StructurePrinter())

Beschikbare visitor‑methoden

Methode‑paarKnooptype
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Navigeren omhoog in de boom

Elke knoop exposeert ParentNode en een Document eigenschap om omhoog te navigeren:

from aspose.note import Document, RichText

doc = Document("MyNotes.one")
for rt in doc.GetChildNodes(RichText):
    parent = rt.ParentNode   # OutlineElement, TableCell, Title, etc.
    root = rt.Document       # always the Document root
    print(f"  '{rt.Text.strip()!r}' parent={type(parent).__name__}")
    break

Methoden voor kindbeheer

CompositeNode biedt ook in‑memory kindbeheer (handig voor programmatische documentconstructie, hoewel terugschrijven naar .one niet ondersteund):

MethodeBeschrijving
node.FirstChildEerste directe kind of None
node.LastChildLaatste directe kind of None
node.AppendChildLast(child)Kind toevoegen aan het einde
node.AppendChildFirst(child)Kind toevoegen aan het begin
node.InsertChild(index, child)Invoegen op positie
node.RemoveChild(child)Een kind verwijderen

Knooppunten tellen met een visitor

from aspose.note import Document, DocumentVisitor, Page, RichText, Image

class Counter(DocumentVisitor):
    def __init__(self):
        self.pages = self.texts = self.images = 0

    def VisitPageStart(self, page: Page) -> None:
        self.pages += 1

    def VisitRichTextStart(self, rt: RichText) -> None:
        self.texts += 1

    def VisitImageStart(self, img: Image) -> None:
        self.images += 1

doc = Document("MyNotes.one")
c = Counter()
doc.Accept(c)
print(f"Pages={c.pages}  RichText={c.texts}  Images={c.images}")

De juiste traversatiemethode kiezen

ScenarioBeste aanpak
Vind alle knooppunten van één type (bijv. alle RichText)GetChildNodes(RichText)
Alleen directe kinderen itererenfor child in node
Doorloop de boom met context (diepte, ouderstatus)DocumentVisitor
Navigeer van inhoud naar boven tot de ouder of rootnode.ParentNode / node.Document

Gerelateerde bronnen:

 Nederlands