Πώς να διασχίσετε το DOM του εγγράφου OneNote στο Python

Πώς να διασχίσετε το DOM του εγγράφου OneNote στο 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, άμεση επανάληψη, και DocumentVisitor.


Το Μοντέλο Αντικειμένου Εγγράφου

Το OneNote DOM είναι ένα αυστηρό δέντρο:

Document
  ├── Page
  │     ├── Title
  │     │     ├── TitleText (RichText)
  │     │     ├── TitleDate (RichText)
  │     │     └── TitleTime (RichText)
  │     └── Outline
  │           └── OutlineElement
  │                 ├── RichText
  │                 ├── Image
  │                 ├── AttachedFile
  │                 └── Table
  │                       └── TableRow
  │                             └── TableCell
  │                                   └── RichText / Image
  └── Page  (next page ...)

Κάθε κόμβος κληρονομεί από Node. Οι κόμβοι που έχουν παιδιά κληρονομούν από CompositeNode.


Μέθοδος 1: GetChildNodes (Αναδρομική, Φιλτραρισμένη κατά τύπο)

CompositeNode.GetChildNodes(Type) εκτελεί μια αναδρομική αναζήτηση βάθους-πρώτα σε ολόκληρο το υποδέντρο και επιστρέφει μια επίπεδη λίστα όλων των κόμβων που ταιριάζουν με τον δοσμένο τύπο. Αυτή είναι η πιο βολική προσέγγιση για εξαγωγή περιεχομένου:

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)}")

Περιορίστε την αναζήτηση σε μία σελίδα καλώντας GetChildNodes στο Page αντί για 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")

Μέθοδος 2: Άμεση Επανάληψη Παιδιών

for child in node διατρέχει το άμεσο παιδιά ενός CompositeNode. Χρησιμοποιήστε το όταν χρειάζεστε ένα συγκεκριμένο επίπεδο της ιεραρχίας:

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__}")

Μέθοδος 3: DocumentVisitor

DocumentVisitor παρέχει ένα πρότυπο επισκέπτη για δομημένη διάσχιση. Υπερκαλύψτε μόνο το VisitXxxStart/End μεθόδους που χρειάζεστε. Ο επισκέπτης ενεργοποιείται καλώντας 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())

Διαθέσιμες Μέθοδοι Επισκέπτη

Ζεύγος μεθόδωνΤύπος κόμβου
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Πλοήγηση προς τα Πάνω στο Δέντρο

Κάθε κόμβος εκθέτει ParentNode και ένα Document ιδιότητα για πλοήγηση προς τα πάνω:

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

Μέθοδοι Διαχείρισης Παιδιών

CompositeNode επίσης εκθέτει διαχείριση παιδιών στη μνήμη (χρήσιμη για προγραμματιστική κατασκευή εγγράφων, αν και η επαναγραφή σε .one δεν υποστηρίζεται):

ΜέθοδοςΠεριγραφή
node.FirstChildΠρώτο άμεσο παιδί ή None
node.LastChildΤελευταίο άμεσο παιδί ή None
node.AppendChildLast(child)Προσθήκη παιδιού στο τέλος
node.AppendChildFirst(child)Προσθήκη παιδιού στην αρχή
node.InsertChild(index, child)Εισαγωγή στη θέση
node.RemoveChild(child)Αφαίρεση παιδιού

Καταμέτρηση Κόμβων με Επισκέπτη

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}")

Επιλογή της Κατάλληλης Μεθόδου Διάσχισης

ΣενάριοΚαλύτερη προσέγγιση
Εύρεση όλων των κόμβων ενός τύπου (π.χ. όλα τα RichText)GetChildNodes(RichText)
Επανάληψη μόνο των άμεσων παιδιώνfor child in node
Περπάτημα του δέντρου με συμφραζόμενα (βάθος, κατάσταση γονέα)DocumentVisitor
Πλοήγηση από το περιεχόμενο προς τα πάνω μέχρι τον γονέα ή τη ρίζαnode.ParentNode / node.Document

Σχετικοί Πόροι:

 Ελληνικά