Cara Menelusuri DOM Dokumen OneNote dalam Python

Cara Menelusuri DOM Dokumen OneNote dalam 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, iterasi langsung, dan DocumentVisitor.


Model Objek Dokumen

DOM OneNote adalah pokok yang ketat:

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

Setiap node mewarisi daripada Node. Node yang mempunyai anak mewarisi daripada CompositeNode.


Kaedah 1: GetChildNodes (Rekursif, Ditapis Mengikut Jenis)

CompositeNode.GetChildNodes(Type) melakukan carian depth-first secara rekursif ke seluruh subpokok dan mengembalikan senarai rata semua node yang sepadan dengan jenis yang diberikan. Ini adalah pendekatan yang paling mudah untuk pengekstrakan kandungan:

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

Skopkan carian kepada satu halaman dengan memanggil GetChildNodes pada Page bukannya 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")

Kaedah 2: Iterasi Anak Secara Langsung

for child in node mengiterasi segera anak bagi a CompositeNode. Gunakan ini apabila anda memerlukan satu tahap khusus dalam hierarki:

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

Kaedah 3: DocumentVisitor

DocumentVisitor menyediakan corak pelawat untuk penelusuran berstruktur. Override hanya VisitXxxStart/End kaedah yang anda perlukan. Pelawat dihantar dengan memanggil 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())

Kaedah Pelawat yang Tersedia

Pasangan kaedahJenis nod
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Menavigasi Ke Atas Pokok

Setiap nod mendedahkan ParentNode dan satu Document sifat untuk menavigasi ke atas:

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

Kaedah Pengurusan Anak

CompositeNode juga mendedahkan pengurusan anak dalam memori (berguna untuk pembinaan dokumen secara programatik, walaupun penulisan kembali ke .one tidak disokong):

KaedahPenerangan
node.FirstChildAnak langsung pertama atau None
node.LastChildAnak langsung terakhir atau None
node.AppendChildLast(child)Tambah anak di akhir
node.AppendChildFirst(child)Tambah anak di permulaan
node.InsertChild(index, child)Sisip pada kedudukan
node.RemoveChild(child)Buang anak

Kira Nod Dengan 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}")

Memilih Kaedah Traversal yang Betul

SenarioPendekatan terbaik
Cari semua nod satu jenis (contoh: semua RichText)GetChildNodes(RichText)
Ulangi hanya anak langsungfor child in node
Lalui pokok dengan konteks (kedalaman, keadaan ibu bapa)DocumentVisitor
Navigasi dari kandungan ke atas kepada ibu bapa atau akarnode.ParentNode / node.Document

Sumber Berkaitan:

 Bahasa Melayu