डॉक्यूमेंट नोड ट्री के साथ काम करना
डॉक्यूमेंट नोड ट्री के साथ काम करना
यह गाइड दिखाता है कि कैसे डॉक्यूमेंट की संरचना को सीधे उसके नोड ट्री के माध्यम से नेविगेट और बदलें — वह ऑब्जेक्ट मॉडल जिस पर Document, Section, Paragraph, Run, Table, और हर अन्य डॉक्यूमेंट तत्व निर्मित होते हैं। डॉक्यूमेंट में हर तत्व Node से व्युत्पन्न होता है, और वह तत्व जो बच्चों को धारण कर सकता है CompositeNode से व्युत्पन्न होता है, इसलिए इन दो बेस क्लासेज़ को समझना यह समझाता है कि ऐसी सामग्री के साथ कैसे काम किया जाए जिसका कोई समर्पित हेल्पर API अभी तक कवर नहीं करता।
नोड और CompositeNode बेस क्लासेज़
Node डॉक्यूमेंट ट्री में प्रत्येक ऑब्जेक्ट के लिए एब्स्ट्रैक्ट बेस क्लास है। यह NodeType (एक enum मान जो यह पहचानता है कि यह किस प्रकार का नोड है), ParentNode (परिधि CompositeNode), Document (स्वामित्व वाला डॉक्यूमेंट), और PreviousSibling/NextSibling को उजागर करता है जिससे समान स्तर पर नोड्स के बीच चल सकते हैं। Node.IsComposite यह बताता है कि कोई नोड बच्चों को समाहित कर सकता है या नहीं। CompositeNode कंटेनर एलिमेंट्स के लिए Node को विस्तारित करता है — FirstChild, LastChild, और Count इसके तत्कालीन बच्चों का वर्णन करते हैं, और HasChildNodes यह रिपोर्ट करता है कि कोई मौजूद हैं या नहीं। CompositeNode.GetChildNodes(nodeType, isDeep) किसी दिए गए NodeType के सभी बच्चों को पुनः प्राप्त करता है, वैकल्पिक रूप से पूरे सबट्री (isDeep) को खोजते हुए, केवल सीधे बच्चों के बजाय, और CompositeNode.GetChild(nodeType, index, isDeep) इंडेक्स द्वारा एकल बच्चा लौटाता है।
NodeType एनम
NodeType दस्तावेज़ मॉडल द्वारा परिभाषित प्रत्येक प्रकार के नोड को सूचीबद्ध करता है — संरचनात्मक प्रकार जैसे Document, Section, Body, Paragraph, Table, Row, और Cell; इनलाइन कंटेंट प्रकार जैसे Run, Shape, और Comment; तथा फ़ील्ड-मैकेनरी प्रकार जैसे FieldStart, FieldSeparator, और FieldEnd, जो रन स्ट्रीम के भीतर एक Word फ़ील्ड की सीमाओं और स्विच टेक्स्ट को चिह्नित करते हैं। NodeType मान को GetChildNodes या GetChild को पास करने से खोज ठीक उसी प्रकार के नोड्स तक सीमित हो जाती है, या NodeType.Any पास करके सभी नोड प्रकारों से मेल किया जा सकता है।
ट्री का अन्वेषण और संशोधन
CompositeNode.GetEnumerator() आपको किसी नोड के प्रत्यक्ष बच्चों पर इटररेट करने देता है, और CompositeNode भी SelectNodes(xpath) और SelectSingleNode(xpath) को XPath-आधारित क्वेरीज के लिए सबट्री में लागू करता है। ट्री को संशोधित करने के लिए, AppendChild(newChild) और PrependChild(newChild) बच्चों की शुरुआत या अंत में एक नोड जोड़ते हैं, InsertBefore(newChild, refChild) और InsertAfter(newChild, refChild) मौजूदा बच्चे के सापेक्ष सम्मिलित करते हैं, और RemoveChild(oldChild) या RemoveAllChildren() नोड्स को हटाते हैं। CompositeNode.IndexOf(child) एक बच्चे की स्थिति लौटाता है। Node स्वयं पर, Clone(isCloneChildren) एक कॉपी बनाता है — वैकल्पिक रूप से डीप — और Remove() नोड को उसके पैरेंट से डिस्कनेक्ट करता है। Node.NextPreOrder(rootNode) और PreviousPreOrder(rootNode) ट्री को दस्तावेज़ क्रम में, दिए गए रूट नोड द्वारा सीमित, चरणबद्ध करते हैं, जो बिना पुनरावर्ती कोड के पूरे सबट्री को नोड-बाय-नोड स्कैन करने का सामान्य तरीका है।
नोड संग्रह और परिवर्तन सूचनाएँ
NodeCollection नोड्स का एक ठोस, परिवर्तनशील संग्रह है जो Add(node), Insert(index, node), Remove(node), RemoveAt(index), Clear(), Contains(node), IndexOf(node) और ToArray() को समर्थन देता है, साथ ही एक Count गुण के साथ। NodeList और NodeEnumerator क्वेरी परिणामों पर पढ़ने-शैली के इटररेशन का समर्थन करते हैं, जैसे कि SelectNodes द्वारा लौटाए गए नोड्स। संरचनात्मक परिवर्तन को वास्तविक समय में देखने के लिए, INodeChangingCallback को लागू करें — इसके NodeInserting(args), NodeInserted(args), NodeRemoving(args) और NodeRemoved(args) मेथड्स प्रत्येक एक NodeChangingArgs प्राप्त करते हैं जो प्रभावित Node, उसके OldParent/NewParent, और हुए NodeChangingAction का वर्णन करता है।
DocumentVisitor के साथ नोड्स का दौरा
ट्री को मैन्युअल रूप से चलाए बिना संरचित तरीके से प्रत्येक नोड प्रकार को प्रोसेस करने के लिए, DocumentVisitor को सबक्लास करें और उन नोड प्रकारों के लिए Visit*Start/Visit*End मेथड्स को ओवरराइड करें जिनमें आप रुचि रखते हैं — VisitParagraphStart/VisitParagraphEnd, VisitTableStart/VisitTableEnd, VisitRun, आदि — फिर सबट्री के रूट पर Node.Accept(visitor) को कॉल करके इसे चलाएँ। यह एक मानक पैटर्न है दस्तावेज़ को निर्यात, रूपांतरित या निरीक्षण करने का, बिना हर उपयोग केस के लिए कस्टम पुनरावर्ती ट्रैवर्सल लिखे।
टिप्स और सर्वश्रेष्ठ प्रथाएँ
- जब आपको प्रकार की परवाह किए बिना सभी वंशज चाहिए हों, तो
NodeType.AnyकोGetChildNodes(NodeType.Any, true)के साथ उपयोग करें, बजाय इसके कि आप प्रत्येक प्रकार के लिएGetChildNodesको एक बार कॉल करें। - हाथ से पुनरावर्ती अवरोह लिखने के बजाय, सबट्री की एक सपाट, गैर-पुनरावर्ती स्कैन के लिए
Node.NextPreOrder(rootNode)/PreviousPreOrder(rootNode)को प्राथमिकता दें। - जब एक ही प्रोसेसिंग को कई विभिन्न नोड प्रकारों पर चलाना हो, तो एड-हॉक ट्री-वॉकिंग कोड के बजाय
DocumentVisitorलागू करें। - अज्ञात प्रकार के नोड के साथ काम करते समय
CompositeNodeमें कास्ट करने से पहलेNode.IsCompositeकी जाँच करें। - जब आपको अन्य कोड (जिसमें बिल्ट-इन ऑपरेशन्स भी शामिल हैं) द्वारा किए गए इन्सर्शन या रिमूवल पर प्रतिक्रिया देनी हो, न कि केवल आपके अपने कोड द्वारा सीधे किए गए बदलावों पर, तो एक
INodeChangingCallbackरजिस्टर करें।
सामान्य समस्याएँ
| समस्या | कारण | समाधान |
|---|---|---|
एक Node को CompositeNode में कास्ट करने पर अमान्य-कास्ट त्रुटि आती है | नोड एक लीफ़ प्रकार है (उदाहरण के लिए Run या FieldStart) जो चाइल्ड नहीं रख सकता | पहले Node.IsComposite जाँचें, या कास्ट करने से पहले यह पुष्टि करने के लिए NodeType का उपयोग करें कि नोड कंटेनर प्रकार है |
GetChildNodes केवल सीधे बच्चों को लौटाता है | isDeep को false छोड़ दिया गया था (या जहाँ ओवरलोड डिफ़ॉल्ट रूप से शैलो होता है, वहाँ इसे छोड़ा गया था) | पूरे उपवृक्ष को खोजने के लिए isDeep: true पास करें |
| इसे इटररेट करते समय संग्रह को संशोधित करने से एक त्रुटि उत्पन्न होती है | नोड्स को foreach के भीतर NodeCollection पर या GetChildNodes के परिणाम पर जोड़ा या हटाया गया था | पहले ToArray() के साथ संशोधित करने के लिए नोड्स को मटेरियलाइज़ करें, फिर ट्री को बदलते हुए ऐरे पर इटररेट करें |
कुछ कंटेंट के लिए DocumentVisitor सबक्लास को कॉल नहीं किया जाता है | विज़िटर को Accept() के माध्यम से ऐसे नोड पर बुलाया गया जो लक्ष्य कंटेंट नहीं रखता, या संबंधित Visit* मेथड को ओवरराइड नहीं किया गया था | कंटेंट वाले पूर्वज पर Accept() कॉल करें, और प्रोसेस किए जा रहे नोड प्रकारों से संबंधित प्रत्येक Visit*Start/Visit*End जोड़े को ओवरराइड करें |
FAQ
Node और CompositeNode में क्या अंतर है?
Node वह बेस क्लास है जिससे प्रत्येक दस्तावेज़ तत्व व्युत्पन्न होता है। CompositeNode Node को विस्तारित करता है उन तत्वों के लिए जो चाइल्ड रख सकते हैं (जैसे Body, Paragraph, और Table); लीफ़ तत्व (जैसे Run) सीधे Node से व्युत्पन्न होते हैं और चाइल्ड नहीं रख सकते।
मैं दस्तावेज़ में किसी विशिष्ट प्रकार के सभी नोड्स कैसे खोजूँ?
अपने खोज के मूल नोड पर CompositeNode.GetChildNodes(nodeType, isDeep) को कॉल करें (अक्सर Document स्वयं), वह NodeType पास करें जिसे आप चाहते हैं और isDeep: true ताकि पूरे सबट्री को खोजा जा सके, न कि केवल प्रत्यक्ष बच्चों को।
इटरेट करते समय नोड्स को सुरक्षित रूप से कैसे हटाऊँ?
पहले हटाने वाले नोड्स को एक एरे में एकत्र करें — उदाहरण के लिए NodeCollection.ToArray() के साथ — फिर उस एरे पर इटरेट करें और प्रत्येक नोड पर Remove() को कॉल करें, बजाय इसके कि foreach इटरेट कर रहा हो तब लाइव कलेक्शन को संशोधित किया जाए।
FieldStart, FieldSeparator, और FieldEnd नोड्स क्या हैं?
वे NodeType मान हैं जो रन स्ट्रीम में एम्बेडेड वर्ड फ़ील्ड के तंत्र को चिन्हित करते हैं: FieldStart और FieldEnd फ़ील्ड को बाइंड करते हैं, और FieldSeparator फ़ील्ड के कोड को उसके वर्तमान प्रदर्शित परिणाम से अलग करता है।
मैं दस्तावेज़ में प्रत्येक पैराग्राफ, टेबल, और रन को कैसे प्रोसेस करूँ?
आपको जिन नोड प्रकारों की आवश्यकता है, उनके लिए DocumentVisitor को सबक्लास करें, VisitParagraphStart/VisitParagraphEnd, VisitTableStart/VisitTableEnd, और VisitRun को ओवरराइड करें, फिर इसे चलाने के लिए Accept(visitor) को Document (या किसी भी सबट्री रूट) पर कॉल करें।
API Reference सारांश
| क्लास/मेथड | विवरण |
|---|---|
Node | दस्तावेज़ पेड़ में प्रत्येक नोड के लिए अमूर्त आधार वर्ग |
CompositeNode | संतान रख सकने वाले नोड्स के लिए आधार वर्ग |
CompositeNode.GetChildNodes(nodeType, isDeep) | दिए गए प्रकार के सभी बच्चों को प्राप्त करें, वैकल्पिक रूप से पूरे सबट्री में |
CompositeNode.AppendChild(newChild) / InsertBefore(newChild, refChild) | कंटेनर के अंत में नोड जोड़ें, या मौजूदा चाइल्ड से पहले/बाद में |
NodeType | नोड के प्रकार की पहचान करने वाला एन्युम (Paragraph, Table, Run, FieldStart, आदि) |
NodeCollection | ठोस, परिवर्तनीय Node वस्तुओं का संग्रह |
Node.Clone(isCloneChildren) | एक नोड को कॉपी करें, वैकल्पिक रूप से उसके बच्चों को शामिल करते हुए |
Node.NextPreOrder(rootNode) / PreviousPreOrder(rootNode) | दस्तावेज़ क्रम में एक सबट्री के माध्यम से कदम रखें |
INodeChangingCallback | Callback interface को तब सूचित किया जाता है जब नोड्स सम्मिलित या हटाए जाते हैं |
DocumentVisitor | बेस क्लास संरचित, प्रकार-डिस्पैच्ड ट्रैवर्सल के लिए, Node.Accept(visitor) के माध्यम से |