Cum să parcurgi DOM-ul documentului OneNote în Python

Cum să parcurgi DOM-ul documentului OneNote în 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, iterare directă și DocumentVisitor.


Modelul de Obiecte al Documentului

DOM-ul OneNote este un arbore strict:

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

Fiecare nod moștenește de la Node. Nodurile care au copii moștenesc de la CompositeNode.


Metoda 1: GetChildNodes (Recursiv, Filtrat pe tip)

CompositeNode.GetChildNodes(Type) efectuează o căutare recursivă în adâncime a întregului subarbore și returnează o listă plată cu toate nodurile care corespund tipului specificat. Aceasta este cea mai convenabilă abordare pentru extragerea de conținut:

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

Limitează căutarea la o singură pagină apelând GetChildNodes pe Page în loc de 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: Iterare directă a copiilor

for child in node iterează imediat copii ai unui CompositeNode. Folosește aceasta când ai nevoie de un nivel specific al ierarhiei:

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 furnizează un model de vizitator pentru traversare structurată. Suprascrie doar VisitXxxStart/End metodele de care ai nevoie. Vizitatorul este declanșat prin apelarea 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 de vizitator disponibile

Pereche de metodeTip de nod
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Navigarea în sus în arbore

Fiecare nod expune ParentNode și un Document proprietate pentru a naviga în sus:

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 de gestionare a copiilor

CompositeNode expune, de asemenea, gestionarea copiilor în memorie (utilă pentru construcția programatică a documentului, deși scrierea înapoi către .one nu este suportată):

MetodăDescriere
node.FirstChildPrimul copil direct sau None
node.LastChildUltimul copil direct sau None
node.AppendChildLast(child)Adaugă copil la sfârșit
node.AppendChildFirst(child)Adaugă copil la început
node.InsertChild(index, child)Inserează la poziție
node.RemoveChild(child)Elimină un copil

Numărați nodurile cu un vizitator

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

Alegerea metodei de traversare potrivite

ScenariuCea mai bună abordare
Găsește toate nodurile de un tip (de ex. toate RichText)GetChildNodes(RichText)
Iterează doar copiii direcțifor child in node
Parcurge arborele cu context (adâncime, stare părinte)DocumentVisitor
Navigați din conținut în sus către părintele sau rădăcinanode.ParentNode / node.Document

Resurse conexe:

 Română