Cum să lucrați cu nodurile în .NET
Acest ghid arată cum să parcurgi, să interoghezi și să modifici arborele de noduri al unui document Word direct în Aspose.Words FOSS pentru .NET, utilizând Node and CompositeNode clasele de bază care Document, Section, Paragraph, Table, și fiecare alt element de document este construit pe acestea. Acoperă delimitarea unei căutări prin NodeType, adăugarea și eliminarea nodurilor programatic, reacționarea la modificări structurale și utilizarea DocumentVisitor pentru traversarea bazată pe tip.
Ghid pas cu pas
Pasul 1: Instalaţi pachetul
Aspose.Words FOSS for .NET nu publică încă un pachet NuGet – construiţi biblioteca din sursă în schimb. Clonaţi https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git, apoi construiţi Aspose.Words.sln în configuraţia Release cu SDK-ul .NET și referenţiaţi ansamblul Aspose.Words rezultat din proiectul dumneavoastră. Biblioteca vizează .NET Standard 2.0, astfel că rulează pe .NET Framework 4.6.2+ și .NET 6/8/10.
Pasul 2: Importaţi clasele necesare
Adăugaţi o directivă using Aspose.Words; – Node, CompositeNode, NodeType, NodeCollection, NodeList, INodeChangingCallback și DocumentVisitor se află în spaţiul de nume Aspose.Words alături de Document.
Pasul 3: Înțelege nodul și clasele de bază CompositeNode
Fiecare obiect dintr-un arbore de documente moștenește clasa abstractă Node, care expune NodeType (identificând ce tip de nod este), ParentNode (CompositeNode înconjurător), Document (documentul proprietar) și PreviousSibling / NextSibling pentru a naviga între noduri la același nivel. Verifică Node.IsComposite pentru a afla dacă un anumit nod poate conține copii înainte de a-l converti. CompositeNode extinde Node pentru elemente container — FirstChild, LastChild și Count descriu copiii săi imediati, iar HasChildNodes raportează dacă există vreunul.
Pasul 4: Interoghează copiii după tip
Apelă CompositeNode.GetChildNodes(nodeType, isDeep) pentru a recupera fiecare copil al unui NodeType dat, trecând isDeep: true pentru a căuta în întregul subarbore în loc de doar copiii direcți, sau NodeType.Any pentru a potrivi orice tip de nod, indiferent de tip. CompositeNode.GetChild(nodeType, index, isDeep) recuperează un singur copil potrivit prin index. Pentru tipurile de noduri structurale (Document, Section, Body, Paragraph, Table, Row, Cell), tipurile de conținut în linie (Run, Shape, Comment), și tipurile de mecanism de câmp (FieldStart, FieldSeparator, FieldEnd, care marchează limitele unui câmp Word și textul de comutare în fluxul de rulare), trece valoarea specifică NodeType care identifică ce cauți.
Pasul 5: Execută interogări XPath pe un subarbore
CompositeNode implementează, de asemenea, SelectNodes(xpath) și SelectSingleNode(xpath) pentru interogări bazate pe XPath pe întregul subarbore, returnând potrivirile ca un NodeList (sau un singur Node). CompositeNode.GetEnumerator() suportă un simplu foreach peste copiii direcți ai unui nod când o interogare XPath depășește cerințele sarcinii.
Pasul 6: Adaugă, mută și elimină noduri
Pentru a modifica arborele, apelează AppendChild(newChild) sau PrependChild(newChild) pentru a adăuga un nod la începutul sau sfârșitul copiilor unui container, și InsertBefore(newChild, refChild) sau InsertAfter(newChild, refChild) pentru a insera relativ la un copil existent. RemoveChild(oldChild) elimină un copil, iar RemoveAllChildren() curăță toți copiii dintr-o dată; CompositeNode.IndexOf(child) raportează poziția unui copil. Pe Node în sine, Clone(isCloneChildren) copiază un nod – opțional includând copiii săi – și Remove() detașează nodul de la părinte.
Pasul 7: Materializați nodurile înainte de a modifica o colecție în timp real
Modificarea unei colecții în timp ce o buclă foreach iterează peste ea – fie că este un NodeCollection sau rezultatul lui GetChildNodes – generează o eroare. Apelați ToArray() pe colecție mai întâi pentru a materializa nodurile într-un tablou fix, apoi iterați peste acel tablou în timp ce apelați Remove() sau faceți alte modificări în arbore.
Pasul 8: Scanați un subarbore în ordine de document
Node.NextPreOrder(rootNode) și PreviousPreOrder(rootNode) parcurg arborele în ordine de document, limitate de un nod rădăcină dat – o metodă comună de a scana un subarbore complet nod cu nod fără a scrie cod de traversare recursivă.
Pasul 9: Procesați fiecare tip de nod cu DocumentVisitor
Pentru a procesa multe tipuri diferite de noduri într-un mod structurat, creați o subclasă a clasei abstracte DocumentVisitor și suprascrieți metodele Visit*Start / Visit*End pentru tipurile de noduri care contează – de exemplu VisitParagraphStart / VisitParagraphEnd, VisitSectionStart / VisitSectionEnd, VisitBodyStart / VisitBodyEnd – apoi apelați Node.Accept(visitor) pe rădăcina subarborelui pentru a o rula. Acesta este modelul standard pentru exportarea, transformarea sau inspectarea unui document fără a scrie o traversare recursivă personalizată pentru fiecare caz de utilizare.
Pasul 10: Reacționați la modificări structurale din alt cod
Implementați INodeChangingCallback atunci când codul trebuie să reacționeze la inserări sau eliminări efectuate de alt cod – inclusiv operații încorporate – nu doar la modificări efectuate direct. Metodele sale NodeInserting(args), NodeInserted(args), NodeRemoving(args) și NodeRemoved(args) primesc fiecare un NodeChangingArgs care descrie Node afectat, părintele său vechi și nou, și NodeChangingAction (Insert sau Remove) care a avut loc.
Probleme comune și soluții
Convertirea unui nod la CompositeNode aruncă o eroare de conversie invalidă Nodul este de tip frunză – de exemplu Run or FieldStart – care nu poate conține copii. Verificaţi Node.IsComposite mai întâi, sau folosiţi NodeType pentru a confirma că nodul este de tip container înainte de a face casting.
GetChildNodes returnează copiii direcţi când isDeep este fals isDeep a rămas false (sau omis unde suprasarcina are ca implicit superficial). Transmite isDeep: true to GetChildNodes() pentru a căuta întregul subarbore în loc de copiii imediaţi.
Modificarea unei colecții în timp ce se iterează peste ea aruncă o eroare Nodurile au fost adăugate sau eliminate în interiorul unui foreach peste un NodeCollection sau rezultatul GetChildNodes. Apelați ToArray() mai întâi pentru a materializa nodurile de modificat, apoi iterați peste acel array în timp ce mutați arborele.
O subclasă DocumentVisitor nu este apelată pentru unele conținuturi Vizitatorul a fost invocat prin Accept() pe un nod care nu conține efectiv conținutul țintă, sau metoda corespunzătoare Visit* metoda nu a fost suprascrisă. Apelă Accept() pe un strămoș care conține conținutul și suprascrie fiecare Visit*Start / Visit*End pereche relevantă tipurilor de noduri procesate.
INodeChangingCallback nu este notificat despre o modificare Callback-ul raportează doar modificări pe Document față de care a fost înregistrat. Confirmă că callback-ul este atașat la Document instanța înainte ca modificarea să aibă loc, nu după.
Întrebări frecvente
Care este diferența dintre Node și CompositeNode?
Node este clasa de bază din care derivă fiecare element de document. CompositeNode extinde Node pentru elemente care pot conține copii (cum ar fi Body, Paragraph și Table); elementele frunză, cum ar fi Run, derivă direct din Node și nu pot avea copii.
Cum pot găsi toate nodurile de un anumit tip într-un document?
Apelă CompositeNode.GetChildNodes(nodeType, isDeep) pe nodul care inițiază căutarea – adesea Document în sine – trecând NodeType țintă și isDeep: true pentru a căuta în întreg subarborele, nu doar în copiii direcți.
Cum pot elimina în siguranță nodurile în timpul iterării?
Colectează mai întâi nodurile de eliminat într-un tablou – de exemplu cu NodeCollection.ToArray() – apoi iterează peste acel tablou și apelează Remove() pe fiecare nod, în loc să modifici colecția activă în timp ce un foreach o iterează.
Ce sunt nodurile FieldStart, FieldSeparator și FieldEnd?
Ele sunt valori NodeType care marchează mecanismul unui câmp Word încorporat în fluxul de rulare: FieldStart și FieldEnd leagă câmpul, iar FieldSeparator separă codul câmpului de rezultatul său afișat în prezent.
Cum procesez fiecare paragraf, tabel și run într-un document?
Subclasează DocumentVisitor, suprascrie metodele Visit*Start / Visit*End pentru tipurile de noduri necesare, apoi apelează Accept(visitor) pe Document (sau pe orice rădăcină de subarbore) pentru a o executa.