Cách Duyệt DOM Tài liệu OneNote trong 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, lặp lại trực tiếp, và DocumentVisitor.
Mô hình Đối tượng Tài liệu
DOM OneNote là một cây chặt chẽ:
Document
├── Page
│ ├── Title
│ │ ├── TitleText (RichText)
│ │ ├── TitleDate (RichText)
│ │ └── TitleTime (RichText)
│ └── Outline
│ └── OutlineElement
│ ├── RichText
│ ├── Image
│ ├── AttachedFile
│ └── Table
│ └── TableRow
│ └── TableCell
│ └── RichText / Image
└── Page (next page ...)Mỗi nút kế thừa từ Node. Các nút có con kế thừa từ CompositeNode.
Phương pháp 1: GetChildNodes (Đệ quy, Lọc theo Kiểu)
CompositeNode.GetChildNodes(Type) thực hiện một tìm kiếm đệ quy theo chiều sâu trên toàn bộ cây con và trả về một danh sách phẳng của tất cả các nút khớp với kiểu đã cho. Đây là cách tiếp cận thuận tiện nhất để trích xuất nội dung:
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)}")Giới hạn phạm vi tìm kiếm trong một trang duy nhất bằng cách gọi GetChildNodes trên Page thay vì 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")Phương pháp 2: Lặp Trực Tiếp Các Con
for child in node lặp qua trực tiếp các nút con của một CompositeNode. Sử dụng điều này khi bạn cần một cấp độ cụ thể của cây phân cấp:
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__}")Phương pháp 3: DocumentVisitor
DocumentVisitor cung cấp một mẫu visitor cho việc duyệt có cấu trúc. Ghi đè chỉ các VisitXxxStart/End phương thức bạn cần. Visitor được kích hoạt bằng cách gọi 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())Các Phương Thức Visitor Có Sẵn
| Cặp phương thức | Kiểu nút |
|---|---|
VisitDocumentStart/End | Document |
VisitPageStart/End | Page |
VisitTitleStart/End | Title |
VisitOutlineStart/End | Outline |
VisitOutlineElementStart/End | OutlineElement |
VisitRichTextStart/End | RichText |
VisitImageStart/End | Image |
Duyệt Lên Trên Cây
Mỗi nút cung cấp ParentNode và một Document thuộc tính để di chuyển lên trên:
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__}")
breakCác phương pháp quản lý con
CompositeNode cũng cung cấp quản lý con trong bộ nhớ (hữu ích cho việc xây dựng tài liệu bằng chương trình, mặc dù việc ghi lại vào .one không được hỗ trợ):
| Phương pháp | Mô tả |
|---|---|
node.FirstChild | Con trực tiếp đầu tiên hoặc None |
node.LastChild | Con trực tiếp cuối cùng hoặc None |
node.AppendChildLast(child) | Thêm con vào cuối |
node.AppendChildFirst(child) | Thêm con vào đầu |
node.InsertChild(index, child) | Chèn vào vị trí |
node.RemoveChild(child) | Xóa một con |
Đếm các nút bằng Visitor
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}")Chọn phương pháp duyệt phù hợp
| Kịch bản | Cách tiếp cận tốt nhất |
|---|---|
| Tìm tất cả các nút của một loại (ví dụ: tất cả RichText) | GetChildNodes(RichText) |
| Duyệt chỉ các nút con trực tiếp | for child in node |
| Duyệt cây với ngữ cảnh (độ sâu, trạng thái của nút cha) | DocumentVisitor |
| Điều hướng từ nội dung lên tới nút cha hoặc gốc | node.ParentNode / node.Document |
Tài nguyên liên quan: