Cara Menelusuri DOM Dokumen OneNote di Python

Cara Menelusuri DOM Dokumen OneNote di 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 pohon 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 dari Node. Node yang memiliki anak mewarisi dari CompositeNode.


Metode 1: GetChildNodes (Rekursif, Filter Tipe)

CompositeNode.GetChildNodes(Type) melakukan pencarian depth-first rekursif pada seluruh subtree dan mengembalikan daftar datar semua node yang cocok dengan tipe yang diberikan. Ini adalah pendekatan paling nyaman untuk ekstraksi konten:

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

Batasi pencarian ke satu halaman dengan memanggil GetChildNodes pada Page daripada 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")

Metode 2: Iterasi Anak Langsung

for child in node mengiterasi langsung anak dari sebuah CompositeNode. Gunakan ini ketika Anda membutuhkan satu tingkat spesifik dari 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__}")

Metode 3: DocumentVisitor

DocumentVisitor menyediakan pola visitor untuk penelusuran terstruktur. Ganti hanya VisitXxxStart/End metode yang Anda butuhkan. Visitor dipanggil 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())

Metode Visitor yang Tersedia

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

Menavigasi ke Atas Pohon

Setiap node mengekspos ParentNode dan sebuah Document properti 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

Metode Manajemen Anak

CompositeNode juga mengekspos manajemen anak dalam memori (berguna untuk konstruksi dokumen secara programatik, meskipun penulisan kembali ke .one tidak didukung):

MetodeDeskripsi
node.FirstChildAnak langsung pertama atau None
node.LastChildAnak langsung terakhir atau None
node.AppendChildLast(child)Tambahkan anak di akhir
node.AppendChildFirst(child)Tambahkan anak di awal
node.InsertChild(index, child)Sisipkan pada posisi
node.RemoveChild(child)Hapus sebuah anak

Hitung Node 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 Metode Traversal yang Tepat

SkenarioPendekatan terbaik
Temukan semua node satu tipe (mis. semua RichText)GetChildNodes(RichText)
Iterasi hanya anak langsungfor child in node
Jelajahi pohon dengan konteks (kedalaman, status induk)DocumentVisitor
Navigasi dari konten ke atas ke induk atau akarnode.ParentNode / node.Document

Sumber Daya Terkait:

 Bahasa Indonesia