Comment parcourir le DOM du document OneNote dans 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, itération directe, et DocumentVisitor.
Le modèle d’objet de document
Le DOM OneNote est un arbre strict :
Document
├── Page
│ ├── Title
│ │ ├── TitleText (RichText)
│ │ ├── TitleDate (RichText)
│ │ └── TitleTime (RichText)
│ └── Outline
│ └── OutlineElement
│ ├── RichText
│ ├── Image
│ ├── AttachedFile
│ └── Table
│ └── TableRow
│ └── TableCell
│ └── RichText / Image
└── Page (next page ...)Chaque nœud hérite de Node. Les nœuds qui ont des enfants héritent de CompositeNode.
Méthode 1 : GetChildNodes (récursif, filtré par type)
CompositeNode.GetChildNodes(Type) effectue une recherche récursive en profondeur de tout le sous‑arbre et renvoie une liste plate de tous les nœuds correspondant au type donné. C’est l’approche la plus pratique pour l’extraction de contenu :
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)}")Limitez la recherche à une seule page en appelant GetChildNodes sur Page au lieu 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éthode 2 : itération directe des enfants
for child in node itère le immédiat enfants d’un CompositeNode. Utilisez ceci lorsque vous avez besoin d’un niveau spécifique de la hiérarchie :
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éthode 3 : DocumentVisitor
DocumentVisitor fournit un visitor pattern pour le parcours structuré. Surchargez uniquement le VisitXxxStart/End méthodes dont vous avez besoin. Le visiteur est déclenché en appelant 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éthodes de visiteur disponibles
| Paire de méthodes | Type de nœud |
|---|---|
VisitDocumentStart/End | Document |
VisitPageStart/End | Page |
VisitTitleStart/End | Title |
VisitOutlineStart/End | Outline |
VisitOutlineElementStart/End | OutlineElement |
VisitRichTextStart/End | RichText |
VisitImageStart/End | Image |
Navigation vers le haut de l’arbre
Chaque nœud expose ParentNode et un Document propriété pour naviguer vers le haut :
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éthodes de gestion des enfants
CompositeNode expose également la gestion des enfants in-memory (utile pour la construction programmatique de documents, bien que la réécriture vers .one n’est pas pris en charge) :
| Méthode | Description |
|---|---|
node.FirstChild | Premier enfant direct ou None |
node.LastChild | Dernier enfant direct ou None |
node.AppendChildLast(child) | Ajouter un enfant à la fin |
node.AppendChildFirst(child) | Ajouter un enfant au début |
node.InsertChild(index, child) | Insérer à la position |
node.RemoveChild(child) | Supprimer un enfant |
Compter les nœuds avec un visiteur
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}")Choisir la bonne méthode de traversée
| Scénario | Meilleure approche |
|---|---|
| Trouver tous les nœuds d’un type (par ex. tous les RichText) | GetChildNodes(RichText) |
| Itérer uniquement les enfants directs | for child in node |
| Parcourir l’arbre avec le contexte (profondeur, état du parent) | DocumentVisitor |
| Naviguer depuis le contenu vers le parent ou la racine | node.ParentNode / node.Document |
Ressources associées :