Wie man das OneNote‑Dokument‑DOM in Python durchläuft

Wie man das OneNote‑Dokument‑DOM in Python durchläuft

Aspose.Note FOSS für Python stellt eine OneNote‑Abschnittsdatei als Baum von typisierten Python‑Objekten dar. Das Verständnis, wie man diesen Baum effizient traversiert, ist die Grundlage für alle Inhalte‑Extraktionsaufgaben. Dieser Leitfaden behandelt alle drei Traversierungsansätze: GetChildNodes, direkte Iteration und DocumentVisitor.


Das Document Object Model

Der OneNote-DOM ist ein strenger Baum:

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

Jeder Knoten erbt von Node. Knoten, die Kinder haben, erben von CompositeNode.


Methode 1: GetChildNodes (rekursiv, typgefiltert)

CompositeNode.GetChildNodes(Type) führt eine rekursive Tiefensuche des gesamten Teilbaums durch und gibt eine flache Liste aller Knoten zurück, die dem angegebenen Typ entsprechen. Dies ist der bequemste Ansatz für die Inhaltsextraktion:

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)}")

Beschränken Sie die Suche auf eine einzelne Seite, indem Sie GetChildNodes auf Page anstelle von Document aufrufen:

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: Direkte Kind-Iteration

for child in node iteriert die direkten Kinder eines CompositeNode. Verwenden Sie dies, wenn Sie eine bestimmte Ebene der Hierarchie benötigen:

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 bietet ein Visitor‑Muster für strukturierte Traversierung. Überschreiben Sie nur die VisitXxxStart/End‑Methoden, die Sie benötigen. Der Visitor wird ausgelöst, indem Sie doc.Accept(visitor) aufrufen:

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())

Verfügbare Visitor-Methoden

MethodenpaarKnotentyp
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Navigieren nach oben im Baum

Jeder Knoten stellt ParentNode und eine Document‑Eigenschaft zum Aufwärtsnavigieren bereit:

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 zur Kindverwaltung

CompositeNode bietet außerdem eine In‑Memory‑Kindverwaltung (nützlich für die programmgesteuerte Dokumentenerstellung, obwohl das Zurückschreiben nach .one nicht unterstützt wird):

MethodeBeschreibung
node.FirstChildErstes direktes Kind oder None
node.LastChildLetztes direktes Kind oder None
node.AppendChildLast(child)Kind am Ende hinzufügen
node.AppendChildFirst(child)Kind am Anfang hinzufügen
node.InsertChild(index, child)An Position einfügen
node.RemoveChild(child)Ein Kind entfernen

Knoten zählen mit einem Besucher

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}")

Die richtige Traversalmethode auswählen

SzenarioBeste Vorgehensweise
Alle Knoten eines Typs finden (z. B. alle RichText)GetChildNodes(RichText)
Nur direkte Kinder iterierenfor child in node
Den Baum mit Kontext durchlaufen (Tiefe, Elternzustand)DocumentVisitor
Vom Inhalt zum übergeordneten Element oder zur Wurzel navigierennode.ParentNode / node.Document

Verwandte Ressourcen:

 Deutsch