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 representa un fitxer de secció OneNote com un arbre d’objectes Python tipats. Entendre com recórrer aquest arbre de manera eficient és la base per a totes les tasques d’extracció de contingut. Aquesta guia cobreix els tres enfocaments de recorregut: 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 especificat. 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ó de fills directes

for child in node itera els fills immediats d’un CompositeNode. Utilitza-ho 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ó visitor per a un recorregut estructurat. Sobreescriu només els mètodes VisitXxxStart/End que necessitis. El visitor 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 de visitant disponibles

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

Navegant cap amunt a l’arbre

Cada node exposa ParentNode i una propietat Document 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ó d’infants

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

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

Compta 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 els 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à