Hvordan traversere OneNote-dokument‑DOM i Python

Hvordan traversere OneNote-dokument‑DOM i 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, direkte iterasjon, og DocumentVisitor.


Dokumentobjektmodellen

OneNote‑DOM‑en er et strengt tre:

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

Hver node arver fra Node. Noder som har barn arver fra CompositeNode.


Metode 1: GetChildNodes (rekursiv, type‑filtrert)

CompositeNode.GetChildNodes(Type) utfører et rekursivt dybde‑først søk i hele undertrær og returnerer en flat liste over alle noder som matcher den gitte typen. Dette er den mest praktiske tilnærmingen for innholdsuttrekk:

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

Begrens søket til en enkelt side ved å kalle GetChildNodesPage i stedet for 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")

Metode 2: Direkte barn‑iterasjon

for child in node itererer umiddelbare barn av en CompositeNode. Bruk dette når du trenger ett spesifikt nivå i hierarkiet:

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

Metode 3: DocumentVisitor

DocumentVisitor gir et besøksmønster for strukturert traversering. Overstyr kun VisitXxxStart/End metodene du trenger. Besøkeren blir sendt ved å kalle 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())

Tilgjengelige besøksmetoder

MetodeparNodetype
VisitDocumentStart/EndDocument
VisitPageStart/EndPage
VisitTitleStart/EndTitle
VisitOutlineStart/EndOutline
VisitOutlineElementStart/EndOutlineElement
VisitRichTextStart/EndRichText
VisitImageStart/EndImage

Navigering oppover i treet

Hver node eksponerer ParentNode og en Document egenskap for å navigere oppover:

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

Metoder for håndtering av barn

CompositeNode eksponerer også minnehåndtering av underordnede (nyttig for programmatisk dokumentkonstruksjon, selv om tilbake-skriving til .one støttes ikke):

MetodeBeskrivelse
node.FirstChildFørste direkte barn eller None
node.LastChildSiste direkte barn eller None
node.AppendChildLast(child)Legg til barn på slutten
node.AppendChildFirst(child)Legg til barn i starten
node.InsertChild(index, child)Sett inn på posisjon
node.RemoveChild(child)Fjern et barn

Tell noder med en besøker

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

Velge riktig traverseringsmetode

ScenarioBeste tilnærming
Finn alle noder av en type (f.eks. alle RichText)GetChildNodes(RichText)
Iterer kun direkte barnfor child in node
Gå gjennom treet med kontekst (dybde, foreldrestatus)DocumentVisitor
Naviger fra innholdet opp til forelder eller rotnode.ParentNode / node.Document

Relaterte ressurser:

 Norsk