A dokumentum csomópontfa kezelése

A dokumentum csomópontfa kezelése

A dokumentumcsomópont-fa kezelése

Ez az útmutató bemutatja, hogyan lehet a dokumentum szerkezetét közvetlenül a csomópont-fán keresztül navigálni és manipulálni – az objektummodellt, amelyen a Document, Section, Paragraph, Run, Table és minden egyéb dokumentumelem alapul. A dokumentum minden eleme a Node származik, és minden, gyermekeket tartalmazni képes elem a CompositeNode származik, ezért ezen két alaposztály megértése megmagyarázza, hogyan lehet olyan tartalommal dolgozni, amelyet még egy dedikált segítő API sem fed le.


A Node és a CompositeNode alaposztályok

Node az absztrakt alaposztály minden objektum számára egy dokumentumfában. Közreadja a NodeType (egy enum érték, amely azonosítja, milyen típusú csomópont ez), a ParentNode (a környező CompositeNode), a Document (a tulajdonos dokumentum), valamint a PreviousSibling/NextSibling metódusokat a szintén ugyanazon szinten lévő csomópontok közötti mozgáshoz. A Node.IsComposite jelzi, hogy egy adott csomópont tartalmazhat-e gyermekeket. A CompositeNode kiterjeszti a Node konténerelemekhez – a FirstChild, LastChild és Count leírják a közvetlen gyermekeket, a HasChildNodes pedig jelzi, hogy léteznek-e. A CompositeNode.GetChildNodes(nodeType, isDeep) visszaadja egy adott NodeType összes gyermekét, opcionálisan a teljes alfa (isDeep) keresésével, nem csak a közvetlen gyermekeket, és a CompositeNode.GetChild(nodeType, index, isDeep) egyetlen elemet ad vissza index alapján.

A NodeType Enum

NodeType felsorolja a dokumentummodell által definiált minden csomópont típust – strukturális típusok, mint például Document, Section, Body, Paragraph, Table, Row és Cell; beágyazott tartalomtípusok, mint Run, Shape és Comment; valamint mező-mechanizmus típusok, mint FieldStart, FieldSeparator és FieldEnd, amelyek a Word mező határait és kapcsoló szövegét jelölik a futásfolyamban. Egy NodeType érték átadása a GetChildNodes vagy GetChild függvénynek a keresést pontosan arra a típusra korlátozza, vagy a NodeType.Any átadása minden csomópont típusra illeszkedik.

A fa bejárása és módosítása

CompositeNode.GetEnumerator() lehetővé teszi, hogy egy csomópont közvetlen gyermekein iteráljunk, és CompositeNode emellett megvalósítja a SelectNodes(xpath) és SelectSingleNode(xpath) funkciókat XPath-alapú lekérdezésekhez a részfában. A fa módosításához a AppendChild(newChild) és PrependChild(newChild) egy csomópontot adnak a gyerekek elejéhez vagy végéhez, a InsertBefore(newChild, refChild) és InsertAfter(newChild, refChild) egy meglévő gyerechez viszonyítva szúrnak be, a RemoveChild(oldChild) vagy RemoveAllChildren() pedig eltávolítja a csomópontokat. A CompositeNode.IndexOf(child) visszaadja egy gyermek pozícióját. A Node esetén a Clone(isCloneChildren) másolatot készít — opcionálisan mély másolatot —, a Remove() pedig leválasztja a csomópontot a szülőjéről. A Node.NextPreOrder(rootNode) és PreviousPreOrder(rootNode) a fát dokumentumsorrendben járják be, egy adott gyökércsomópont által korlátozva, ami gyakori módja annak, hogy egy egész részfát csomópontonként beolvassunk rekurzív kód nélkül.

Csomópontgyűjtemények és változásértesítések

NodeCollection egy konkrét, módosítható csomópontgyűjtemény, amely támogatja a Add(node), Insert(index, node), Remove(node), RemoveAt(index), Clear(), Contains(node), IndexOf(node) és ToArray() műveleteket, valamint egy Count tulajdonságot. A NodeList és NodeEnumerator olvasási stílusú iterációt biztosítanak a lekérdezési eredmények felett, például a SelectNodes által visszaadott csomópontok esetén. A strukturális változások megfigyeléséhez, ahogy azok bekövetkeznek, valósítsd meg a INodeChangingCallback — annak NodeInserting(args), NodeInserted(args), NodeRemoving(args) és NodeRemoved(args) metódusai mindegyike kap egy NodeChangingArgs objektumot, amely leírja az érintett Node, annak OldParent/NewParent, és a bekövetkezett NodeChangingAction.

Csomópontok felkeresése a DocumentVisitor segítségével

A fa kézi bejárása nélkül, minden csomóponttípus strukturált feldolgozásához származtass DocumentVisitor osztályt, és írd felül a Visit*Start/Visit*End metódusokat azokhoz a csomóponttípusokhoz, amelyek érdekelnek — VisitParagraphStart/VisitParagraphEnd, VisitTableStart/VisitTableEnd, VisitRun stb. — majd hívd meg a Node.Accept(visitor) metódust a részfa gyökerén, hogy végrehajtsa. Ez a szabványos minta a dokumentum exportálásához, átalakításához vagy vizsgálatához anélkül, hogy minden esethez egyedi rekurzív bejárást kellene írni.


Tippek és bevált gyakorlatok

  • Használd a NodeType.Any elemet a GetChildNodes(NodeType.Any, true)-vel, ha minden leszármazottat szükséges elérni típusfüggetlenül, ahelyett, hogy a GetChildNodes-t típusonként egyszer hívnád meg.
  • Részfák lapos, nem rekurzív beolvasásához részesítsd előnyben a Node.NextPreOrder(rootNode) / PreviousPreOrder(rootNode) megoldást, ahelyett, hogy kézi rekurzív leereszkedést írnál.
  • Implementálja a DocumentVisitor elemet az egyedi, fastruktúrán járó kód helyett, ha ugyanazt a feldolgozást sok különböző csomóponttípuson kell végrehajtani.
  • Ellenőrizze a Node.IsComposite értékét, mielőtt a CompositeNode típusra konvertálna, ismeretlen típusú csomópont esetén.
  • Regisztráljon egy INodeChangingCallback elemet, ha reagálnia kell a más kód által (beleértve a beépített műveleteket) végrehajtott beszúrásokra vagy eltávolításokra, nem csak a saját kódja által közvetlenül végzett változásokra.

Gyakori problémák

ProblémaOkJavítás
A Node CompositeNode-ra történő átkonvertálása invalid-cast hibát eredményezA csomópont egy levél típus (például Run vagy FieldStart), amely nem tarthat gyermekeketElőször ellenőrizze a Node.IsComposite-t, vagy használja a NodeType-t, hogy megerősítse, a csomópont tárolótípus-e, mielőtt átkonvertálná
GetChildNodes csak közvetlen gyermekeket ad visszaisDeep false maradt (vagy kihagyva, ahol a túlterhelés alapértelmezettként sekély)Adja át a isDeep: true értéket a teljes alfa kereséséhez
A gyűjtemény módosítása iterálás közben hibát okozCsomópontok lettek hozzáadva vagy eltávolítva egy foreach NodeCollection vagy a GetChildNodes eredménye alattElőször hozza létre a módosítandó csomópontokat a ToArray() segítségével, majd iteráljon a tömbön, miközben módosítja a fát
Egy DocumentVisitor alosztály nem kerül meghívásra bizonyos tartalom eseténA látogatót a Accept() útján hívták meg egy olyan csomóponton, amely nem tartalmazza a cél tartalmat, vagy a megfelelő Visit* metódust nem írták felülHívja meg a Accept() függvényt egy olyan ősön, amely tartalmazza a tartalmat, és írja felül az összes a feldolgozott csomóponttípusokhoz kapcsolódó Visit*Start/Visit*End párt

FAQ

Mi a különbség a Node és a CompositeNode között?

Node az az alaposztály, amelyből minden dokumentumelem származik. CompositeNode kiterjeszti a Node osztályt olyan elemekhez, amelyek gyermekeket tudnak tartalmazni (például Body, Paragraph és Table); a levél elemek (például Run) közvetlenül a Node osztályból származnak, és nem tarthatnak gyermekeket.

Hogyan találhatom meg egy dokumentumban egy adott típusú összes csomópontot?

Hívd meg a(z) CompositeNode.GetChildNodes(nodeType, isDeep) függvényt azon a csomóponton, amely a keresésed gyökere (gyakran maga a Document), átadva a kívánt NodeType-t és a isDeep: true-t, hogy az egész részfa legyen keresve, nem csak a közvetlen gyermekek.

Hogyan tudok biztonságosan eltávolítani csomópontokat iterálás közben?

Gyűjtsd először egy tömbbe az eltávolítandó csomópontokat — például a(z) NodeCollection.ToArray() segítségével — majd iterálj végig azon a tömbön, és hívd meg a(z) Remove() függvényt minden egyes csomóponton, ahelyett, hogy a foreach iterálás közben módosítaná az élő gyűjteményt.

Mik azok a FieldStart, FieldSeparator és FieldEnd csomópontok?

Ezek NodeType értékek, amelyek a futási adatfolyamban beágyazott Word mező mechanikáját jelölik: a FieldStart és a FieldEnd kötik össze a mezőt, a FieldSeparator pedig elválasztja a mező kódját a jelenleg megjelenített eredménytől.

Hogyan dolgozom fel minden bekezdést, táblázatot és run-t egy dokumentumban?

Származtass le a(z) DocumentVisitor osztályból, felülírd a(z) VisitParagraphStart/VisitParagraphEnd, a(z) VisitTableStart/VisitTableEnd és a(z) VisitRun metódusokat a szükséges csomóponttípusokhoz, majd hívd meg a(z) Accept(visitor) függvényt a(z) Document (vagy bármely részfa gyöke) objektumon, hogy lefusson.


API Reference összefoglaló

Osztály/MódszerLeírás
NodeAbsztrakt alaposztály minden dokumentumfa csomóponthoz
CompositeNodeAlaposztály azoknak a csomópontoknak, amelyek gyermekeket tartalmazhatnak
CompositeNode.GetChildNodes(nodeType, isDeep)Az adott típusú összes gyermek lekérése, opcionálisan a teljes részfán belül
CompositeNode.AppendChild(newChild) / InsertBefore(newChild, refChild)Csomópont hozzáadása egy konténerhez a végén, vagy egy meglévő gyermek előtt/után
NodeTypeEnum, amely meghatározza egy csomópont típusát (Paragraph, Table, Run, FieldStart, és így tovább)
NodeCollectionKonkrét, módosítható Node objektumok gyűjteménye
Node.Clone(isCloneChildren)Másolj egy csomópontot, opcionálisan beleértve a gyermekeket
Node.NextPreOrder(rootNode) / PreviousPreOrder(rootNode)Haladj végig egy részfán a dokumentum sorrendjében
INodeChangingCallbackCallback interfész, amely értesül, amikor csomópontok kerülnek beszúrásra vagy eltávolításra
DocumentVisitorAlaposztály strukturált, típus-alapú diszpécselésű bejáráshoz a Node.Accept(visitor) segítségével

Lásd még:

 Magyar