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ètodes | Tipus de node |
|---|---|
VisitDocumentStart/End | Document |
VisitPageStart/End | Page |
VisitTitleStart/End | Title |
VisitOutlineStart/End | Outline |
VisitOutlineElementStart/End | OutlineElement |
VisitRichTextStart/End | RichText |
VisitImageStart/End | Image |
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__}")
breakMè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ètode | Descripció |
|---|---|
node.FirstChild | Primer 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
| Escenari | Millor enfocament |
|---|---|
| Troba tots els nodes d’un tipus (p. ex. tots els RichText) | GetChildNodes(RichText) |
| Itera només els fills directes | for child in node |
| Recorre l’arbre amb context (profunditat, estat del pare) | DocumentVisitor |
| Navega des del contingut cap al pare o arrel | node.ParentNode / node.Document |
Recursos relacionats: