Ako prechádzať DOM dokumentu OneNote v Python

Ako prechádzať DOM dokumentu OneNote v 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, priame iterovanie a DocumentVisitor.


Objektový model dokumentu

DOM OneNote je prísny strom:

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

Každý uzol dedí od Node. Uzly, ktoré majú poduzly, dedí od CompositeNode.


Metóda 1: GetChildNodes (rekurzívne, filtrované podľa typu)

CompositeNode.GetChildNodes(Type) vykoná rekurzívne hľadanie do hĺbky celého podstromu a vráti plochý zoznam všetkých uzlov zodpovedajúcich danému typu. Toto je najpohodlnejší prístup pre extrakciu obsahu:

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

Obmedzte vyhľadávanie na jednu stránku volaním GetChildNodes na Page namiesto 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")

Metóda 2: Priama iterácia detí

for child in node iteruje bezprostredné poduzly CompositeNode. Použite to, keď potrebujete jednu konkrétnu úroveň hierarchie:

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

Metóda 3: DocumentVisitor

DocumentVisitor poskytuje vzor návštevníka pre štruktúrované prechádzanie. Prepíšte iba VisitXxxStart/End metódy, ktoré potrebujete. Návštevník je spustený volaním 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())

Dostupné metódy návštevníka

Pár metódTyp uzla
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Navigácia smerom hore v strome

Každý uzol vystavuje ParentNode a Document vlastnosť na navigáciu smerom nahor:

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

Metódy správy podriadených

CompositeNode tiež poskytuje správu podriadených v pamäti (užitočné pre programatickú tvorbu dokumentov, hoci spätný zápis do .one nie je podporované):

MetódaPopis
node.FirstChildPrvé priame dieťa alebo None
node.LastChildPosledné priame dieťa alebo None
node.AppendChildLast(child)Pridať dieťa na koniec
node.AppendChildFirst(child)Pridať dieťa na začiatok
node.InsertChild(index, child)Vložiť na pozíciu
node.RemoveChild(child)Odstrániť dieťa

Počítanie uzlov pomocou návštevníka

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

Výber správnej metódy prechádzania

ScenárNajlepší prístup
Nájsť všetky uzly jedného typu (napr. všetky RichText)GetChildNodes(RichText)
Prechádzať iba priame detifor child in node
Prechádzať strom s kontextom (hĺbka, stav rodiča)DocumentVisitor
Navigovať od obsahu hore k rodičovi alebo koreňunode.ParentNode / node.Document

Súvisiace zdroje:

 Slovenčina