Kako proći kroz OneNote Document DOM u Python

Kako proći kroz OneNote Document DOM u 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, izravna iteracija i DocumentVisitor.


Model objekta dokumenta

OneNote DOM je strogo stablo:

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

Svaki čvor nasljeđuje od Node. Čvorovi koji imaju podčvorove nasljeđuju od CompositeNode.


Metoda 1: GetChildNodes (rekurzivno, filtrirano po tipu)

CompositeNode.GetChildNodes(Type) izvršava rekurzivno pretraživanje dubine prvog (depth‑first) cijelog podstabla i vraća ravnu listu svih čvorova koji odgovaraju zadanoj vrsti. Ovo je najprikladniji pristup za izdvajanje sadržaja:

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

Ograničite pretraživanje na jednu stranicu pozivom GetChildNodes na Page umjesto 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")

Metoda 2: Izravna iteracija djece

for child in node iterira izravne djeca od CompositeNode. Koristite ovo kada vam je potrebna jedna određena razina hijerarhije:

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

Metoda 3: DocumentVisitor

DocumentVisitor omogućuje obrazac posjetitelja za strukturirano prolazak. Nadjačajte samo VisitXxxStart/End metode koje su vam potrebne. Posjetitelj se aktivira pozivanjem 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())

Dostupne metode posjetitelja

Par metodaVrsta čvora
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Navigacija prema gore kroz stablo

Svaki čvor izlaže ParentNode i Document svojstvo za navigaciju prema gore:

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

Metode upravljanja podređenim čvorovima

CompositeNode također izlaže upravljanje podređenim elementima u memoriji (korisno za programsku izgradnju dokumenata, iako povratno pisanje u .one nije podržano):

MetodaOpis
node.FirstChildPrvo izravno dijete ili None
node.LastChildPosljednje izravno dijete ili None
node.AppendChildLast(child)Dodaj dijete na kraj
node.AppendChildFirst(child)Dodaj dijete na početak
node.InsertChild(index, child)Umetni na poziciju
node.RemoveChild(child)Ukloni dijete

Brojanje čvorova pomoću posjetitelja

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

Odabir pravog načina obilaska

ScenarijNajbolji pristup
Pronađi sve čvorove jednog tipa (npr. sve RichText)GetChildNodes(RichText)
Iteriraj samo izravna djecafor child in node
Prođi kroz stablo s kontekstom (dubina, stanje roditelja)DocumentVisitor
Navigiraj od sadržaja prema roditelju ili korijenunode.ParentNode / node.Document

Povezani resursi:

 Hrvatski