Jak procházet DOM dokumentu OneNote v Pythonu
Aspose.Note FOSS for Python představuje soubor sekce OneNote jako strom typovaných objektů Pythonu. Porozumění tomu, jak efektivně procházet tento strom, je základem pro všechny úlohy extrakce obsahu. Tento průvodce pokrývá všechny tři přístupy k procházení: GetChildNodes, přímou iteraci a DocumentVisitor.
Objektový model dokumentu
DOM OneNote je přísný strom:
Document
├── Page
│ ├── Title
│ │ ├── TitleText (RichText)
│ │ ├── TitleDate (RichText)
│ │ └── TitleTime (RichText)
│ └── Outline
│ └── OutlineElement
│ ├── RichText
│ ├── Image
│ ├── AttachedFile
│ └── Table
│ └── TableRow
│ └── TableCell
│ └── RichText / Image
└── Page (next page ...)Každý uzel dědí z Node. Uzly, které mají podřízené, dědí z CompositeNode.
Metoda 1: GetChildNodes (rekurzivní, filtrováno podle typu)
CompositeNode.GetChildNodes(Type) provádí rekurzivní prohledávání do hloubky celého podstromu a vrací plochý seznam všech uzlů odpovídajících zadanému typu. Toto je nejpohodlnější přístup pro extrakci obsahu:
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)}")Omezte vyhledávání na jednu stránku voláním GetChildNodes na Page místo 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: Přímá iterace potomků
for child in node iteruje bezprostřední podřízené prvky CompositeNode. Použijte to, když potřebujete jednu konkrétní úroveň hierarchie:
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 poskytuje vzor návštěvníka pro strukturované procházení. Přepište pouze metody VisitXxxStart/End, které potřebujete. Návštěvník je vyvolán voláním 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())Dostupné metody návštěvníka
| Pár metod | Typ uzlu |
|---|---|
VisitDocumentStart/End | Document |
VisitPageStart/End | Page |
VisitTitleStart/End | Title |
VisitOutlineStart/End | Outline |
VisitOutlineElementStart/End | OutlineElement |
VisitRichTextStart/End | RichText |
VisitImageStart/End | Image |
Navigování nahoru po stromu
Každý uzel poskytuje ParentNode a Document vlastnost pro navigaci nahoru:
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__}")
breakMetody správy dětí
CompositeNode také poskytuje správu podřízených v paměti (užitečné pro programovou konstrukci dokumentu, i když zápis zpět do .one není podporován):
| Metoda | Popis |
|---|---|
node.FirstChild | První přímý podřízený nebo None |
node.LastChild | Poslední přímý podřízený nebo None |
node.AppendChildLast(child) | Přidat podřízený na konec |
node.AppendChildFirst(child) | Přidat podřízený na začátek |
node.InsertChild(index, child) | Vložit na pozici |
node.RemoveChild(child) | Odstranit podřízený |
Počítání uzlů pomocí návštěvníka
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}")Výběr správné metody procházení
| Scénář | Nejlepší přístup |
|---|---|
| Najít všechny uzly jednoho typu (např. všechny RichText) | GetChildNodes(RichText) |
| Iterovat pouze přímé potomky | for child in node |
| Procházet strom s kontextem (hloubka, stav rodiče) | DocumentVisitor |
| Navigovat od obsahu nahoru k rodiči nebo kořeni | node.ParentNode / node.Document |
Související zdroje: