Com recórrer el DOM del document OneNote en Python

Com recórrer el DOM del document OneNote en 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, iteració directa, i DocumentVisitor.


El model d’objecte de document

El DOM de OneNote és un arbre estricte:

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

Cada node hereta de Node. Els nodes que tenen fills hereten de CompositeNode.


Mètode 1: GetChildNodes (Recursiu, Filtrat per tipus)

CompositeNode.GetChildNodes(Type) realitza una cerca recursiva en profunditat de tot el subarbre i retorna una llista plana de tots els nodes que coincideixen amb el tipus indicat. Aquesta és l’enfocament més còmode per a l’extracció de contingut:

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

Limita la cerca a una sola pàgina cridant GetChildNodes a Page en lloc 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")

Mètode 2: Iteració directa de fills

for child in node itera el immediat fills d’un CompositeNode. Utilitza això quan necessites un nivell específic de la jerarquia:

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

Mètode 3: DocumentVisitor

DocumentVisitor proporciona un patró de visitador per a recorregut estructurat. Sobreescriu només el VisitXxxStart/End mètodes que necessites. El visitador es despacha cridant 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())

Mètodes visitor disponibles

Parell de mètodesTipus de node
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Navegant cap amunt en l’arbre

Cada node exposa ParentNode i un Document propietat per navegar cap amunt:

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

Mètodes de gestió de fills

CompositeNode també exposa la gestió de fills en memòria (útil per a la construcció programàtica de documents, encara que l’escriptura de tornada a .one no està suportat):

MètodeDescripció
node.FirstChildPrimer fill directe o None
node.LastChildÚltim fill directe o None
node.AppendChildLast(child)Afegeix fill al final
node.AppendChildFirst(child)Afegeix fill al principi
node.InsertChild(index, child)Insereix a la posició
node.RemoveChild(child)Elimina un fill

Comptar nodes amb un visitador

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

Escollint el mètode de recorregut adequat

EscenariMillor enfocament
Troba tots els nodes d’un tipus (p. ex. tots els RichText)GetChildNodes(RichText)
Itera només fills directesfor child in node
Recorre l’arbre amb context (profunditat, estat del pare)DocumentVisitor
Navega des del contingut cap al pare o arrelnode.ParentNode / node.Document

Recursos relacionats:

 Català