Jak pracovat s uzly v .NET

Jak pracovat s uzly v .NET

Tento návod ukazuje, jak procházet, dotazovat se a upravovat strom uzlů Word dokumentu přímo v Aspose.Words FOSS pro .NET, pomocí Node and CompositeNode základních tříd, které Document, Section, Paragraph, Table, a všechny ostatní prvky dokumentu jsou na nich postaveny. Pokrývá omezení vyhledávání podle NodeType, přidávání a odstraňování uzlů programově, reakci na strukturální změny a používání DocumentVisitor pro typově rozeslané procházení.

Průvodce krok po kroku

Krok 1: Nainstalujte balíček

Aspose.Words FOSS for .NET zatím nepublikuje balíček NuGet – místo toho sestavte knihovnu ze zdrojového kódu. Naklonujte https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git, poté sestavte Aspose.Words.sln v konfiguraci Release s .NET SDK a odkažte na vzniklou Aspose.Words assembly ve svém projektu. Knihovna cílí na .NET Standard 2.0, takže běží na .NET Framework 4.6.2+ a .NET 6/8/10.


Krok 2: Importujte požadované třídy

Přidejte direktivu using Aspose.Words; – Node, CompositeNode, NodeType, NodeCollection, NodeList, INodeChangingCallback a DocumentVisitor se nacházejí v jmenném prostoru Aspose.Words vedle Document.


Krok 3: Pochopit uzel a základní třídy CompositeNode

Každý objekt ve stromu dokumentu dědí z abstraktní třídy Node, která poskytuje NodeType (identifikující typ uzlu), ParentNode (obalující CompositeNode), Document (vlastnický dokument) a PreviousSibling / NextSibling pro pohyb mezi uzly na stejné úrovni. Zkontrolujte Node.IsComposite, abyste zjistili, zda může daný uzel obsahovat podřízené prvky, předtím než jej přetypujete. CompositeNode rozšiřuje Node pro kontejnerové prvky — FirstChild, LastChild a Count popisují jeho přímé podřízené prvky a HasChildNodes hlásí, zda nějaké existují.


Krok 4: Dotazovat se na podřízené podle typu

Zavolejte CompositeNode.GetChildNodes(nodeType, isDeep) pro získání každého podřízeného daného NodeType, přičemž předáte isDeep: true k prohledání celého podstromu místo pouze přímých podřízených, nebo NodeType.Any pro shodu se všemi typy uzlů bez ohledu na druh. CompositeNode.GetChild(nodeType, index, isDeep) získá jeden odpovídající podřízený podle indexu. Pro typy strukturálních uzlů (Document, Section, Body, Paragraph, Table, Row, Cell), typy vloženého obsahu (Run, Shape, Comment) a typy pole-mechaniky (FieldStart, FieldSeparator, FieldEnd, které označují hranice pole Word a přepínací text ve streamu běhu), předávejte konkrétní hodnotu NodeType, která určuje, co hledáte.


Krok 5: Spouštět XPath dotazy napříč podstromem

CompositeNode také implementuje SelectNodes(xpath) a SelectSingleNode(xpath) pro XPath-založené dotazy napříč podstromem, vracející shody jako NodeList (nebo jediný Node). CompositeNode.GetEnumerator() podporuje prostý foreach nad přímými podřízenými uzlu, když XPath dotaz přesahuje požadavky úkolu.


Krok 6: Přidávat, přesouvat a odstraňovat uzly

Pro úpravu stromu zavolejte AppendChild(newChild) nebo PrependChild(newChild) pro přidání uzlu na začátek nebo konec podřízených kontejneru a InsertBefore(newChild, refChild) nebo InsertAfter(newChild, refChild) pro vložení relativně k existujícímu podřízenému. RemoveChild(oldChild) odstraní jeden podřízený a RemoveAllChildren() vymaže všechny podřízené najednou; CompositeNode.IndexOf(child) uvádí pozici podřízeného. Na samotném Node Clone(isCloneChildren) kopíruje uzel – volitelně včetně jeho podřízených – a Remove() odpojí uzel od jeho nadřazeného.


Krok 7: Materializovat uzly před mutací živé kolekce

Úprava kolekce, zatímco foreach smyčka po ní iteruje – ať už se jedná o NodeCollection nebo výsledek GetChildNodes – vyvolá chybu. Nejprve zavolejte ToArray() na kolekci, aby se uzly materializovaly do pevného pole, a poté iterujte přes toto pole při volání Remove() nebo provádění dalších změn ve stromu.


Krok 8: Procházet podstrom v pořadí dokumentu

Node.NextPreOrder(rootNode) a PreviousPreOrder(rootNode) procházejí strom v pořadí dokumentu, omezené daným kořenovým uzlem – běžný způsob, jak prozkoumat celý podstrom uzel po uzlu, aniž byste psali rekurzivní kód pro průchod.


Krok 9: Zpracovat každý typ uzlu pomocí DocumentVisitor

Pro zpracování mnoha různých typů uzlů strukturovaným způsobem podtříděte abstraktní třídu DocumentVisitor a přepište metody Visit*Start / Visit*End pro typy uzlů, na kterých vám záleží – například VisitParagraphStart / VisitParagraphEnd, VisitSectionStart / VisitSectionEnd, VisitBodyStart / VisitBodyEnd – poté zavolejte Node.Accept(visitor) na kořen podstromu, aby se spustil. Toto je standardní vzor pro export, transformaci nebo inspekci dokumentu, aniž byste psali vlastní rekurzivní průchod pro každý případ použití.


Krok 10: Reagovat na strukturální změny z jiného kódu

Implementujte INodeChangingCallback, když kód potřebuje reagovat na vložení nebo odebrání provedené jiným kódem – včetně vestavěných operací – nikoli jen na změny provedené přímo. Jeho metody NodeInserting(args), NodeInserted(args), NodeRemoving(args) a NodeRemoved(args) každá přijímají NodeChangingArgs, který popisuje dotčený Node, jeho starého a nového rodiče a NodeChangingAction (Insert nebo Remove), ke kterému došlo.

Časté problémy a opravy

Přetypování uzlu na CompositeNode vyvolá chybu neplatného přetypování Uzel je typu list – například Run or FieldStart – který nemůže mít podřízené uzly. Zkontrolujte Node.IsComposite nejprve, nebo použijte NodeType k potvrzení, že uzel je typu kontejner před přetypováním.

GetChildNodes vrací přímé potomky, když je isDeep false isDeep byl ponechán false (nebo vynecháno, kde přetížení výchozí na mělké). Předávejte isDeep: true to GetChildNodes() k prohledání celého podstromu místo okamžitých potomků.

Úprava kolekce během její iterace vyvolá chybu Uzly byly přidány nebo odebrány uvnitř a foreach přes a NodeCollection nebo výsledek GetChildNodes. Zavolejte ToArray() nejprve materializovat uzly k úpravě, poté iterovat přes toto pole při mutaci stromu.

A DocumentVisitor podtřída není volána pro některý obsah Návštěvník byl vyvolán přes Accept() na uzlu, který ve skutečnosti neobsahuje cílový obsah, nebo odpovídající Visit* metoda nebyla přepsána. Zavolejte Accept() na předka, který obsahuje obsah, a přepište každý Visit*Start / Visit*End pár související s typy uzlů, které jsou zpracovávány.

INodeChangingCallback není upozorněn na změnu Callback hlásí změny pouze na Document na který byl zaregistrován. Ověřte, že je callback připojen k správnému Document instanci před tím, než dojde ke změně, ne po ní.

Často kladené otázky

Jaký je rozdíl mezi Node a CompositeNode?

Node je základní třída, ze které dědí každý prvek dokumentu. CompositeNode rozšiřuje Node pro prvky, které mohou obsahovat podřízené (například Body, Paragraph a Table); listové prvky jako Run dědí přímo z Node a nemohou mít podřízené.

Jak najdu všechny uzly konkrétního typu v dokumentu?

Zavolejte CompositeNode.GetChildNodes(nodeType, isDeep) na uzlu, který je kořenem hledání – často přímo na Document – a předáte cílový NodeType a isDeep: true, aby se prohledal celý podstrom, ne jen přímé potomky.

Jak bezpečně odstranit uzly během iterace?

Nejprve shromážděte uzly k odstranění do pole – například pomocí NodeCollection.ToArray() – poté iterujte přes toto pole a zavolejte Remove() na každý uzel, místo aby se měnila živá kolekce během iterace foreach.

Co jsou uzly FieldStart, FieldSeparator a FieldEnd?

Jedná se o hodnoty NodeType, které označují mechanismus Word pole vloženého do proudu běhu: FieldStart a FieldEnd svazují pole a FieldSeparator odděluje kód pole od jeho aktuálně zobrazeného výsledku.

Jak mohu zpracovat každý odstavec, tabulku a úsek v dokumentu?

Vytvořte podtřídu DocumentVisitor, přepište metody Visit*Start / Visit*End pro potřebné typy uzlů a pak zavolejte Accept(visitor) na Document (nebo na jakýkoli kořen podstromu), aby se spustilo.

Viz také:

 Čeština