Dear Denny, Thx. a lot for your reply. Never thought to look at W3C (shame on me!). That clears things up a little bit.
Thankfully Joerg > -----Urspr�ngliche Nachricht----- > Von: Denny Vrandecic [mailto:[EMAIL PROTECTED] > Gesendet: Mittwoch, 10. Dezember 2003 13:03 > An: [EMAIL PROTECTED]; [EMAIL PROTECTED] > Betreff: Re: DOMNodeIterator - Position after deleting a node > > > The DOM standard describes the behaviour of NodeIterator > after deletion in DOM Level 2 Traversal and Range refer > http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-2000 1113/traversal.html#Iterator-overview > > I quote the appropriate paragraphs: > "If the reference node is removed from the list being > iterated over, a different node is selected as the reference > node. If the reference node's position is before that of the > NodeIterator, which is usually the case after > nextNode() has been called, the nearest node before the > iterator is chosen as the new reference node. Suppose we > remove the "D" node, starting from the following state: A B C > [D] * F G H I The "C" node becomes the new reference node, > since it is the nearest node to the NodeIterator that is > before the iterator: > > A B [C] * F G H I > If the reference node is after the NodeIterator, which is > usually the case after previousNode() has been called, the > nearest node after the iterator is chosen as the new > reference node. Suppose we remove "E", starting from the > following state: > > A B C D * [E] F G H I > The "F" node becomes the new reference node, since it is the > nearest node to the NodeIterator that is after the iterator: > > A B C D * [F] G H I"I hope this helps.Best regards,Denny > ----- Original Message ----- > From: "Joerg Toellner" <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Wednesday, December 10, 2003 9:00 AM > Subject: DOMNodeIterator - Position after deleting a node > > > > Dear Group and Xerces-Gods, > > > > maybe a simple question for you but a big problem for me. Haven't > > found a hint within doc, faq and group (or maybe i'm to dumb to > > understand it). > > > > The situation: > > -------------- > > I have to "cleanup" a DOMTree after processing it. I load a > "template" > > XML File, parse it, change/add/delete some > nodes/values/attributes as > > neccesary and save it again under another filename. After > manipulating > > the XML-Document in memory maybe in a ugly state (not in > the meaning > > of correctness. It is still wellformed of course). But some > nodes are > > empty after processing (has had a value before processing). Some > > attributes may be obsolete now, i don't want comment-nodes in the > > resulting xml file (against i want them for documentation in the > > template of course) a.s.o. > > > > So after all processing i do a (let me call it a) > "cleanup". I create > > a DOMNodeIterator for the whole doctree. FastForward (with > nextNode) > > to the last node and traverse the iterator backwards (with > > previousNode) researching each node and do what have to be > done with > > it. > > > > Now my question: > > ---------------- > > As stated above in some cases i need to remove the actual node (and > > the whole subtree under it). This works fine, but then i'm in doubt > > about the position of the DOMNodeIterator as i think it is > LIVE, isn't > > it? Which node i'll get if i call nextNode/previousNode > after deleting > > the actual Node? > > > > Please find my related code below for your information what > i do yet. > > What must i do to set my nd-variable (see my code) to the correct > > previous node of the now deleted actual node? I found no > method to get > > the actual node from the DOMNodeIterator without moving the > > actualpointer of the iterator one forward or backward. Or > I'm missing > > here sth.? Is the best/only way to be sure that i have the > right node > > to do a nextNode/previousNode call to get the now actual > node without > > overjumping a node which then will not being processed/cleanup-ed? > > > > I'm always thankful for suggestions to improve my surely > inefficient > > and hopefully not to buggy code (who laughs there? *GRUMBLE*) :-)). > > Please if you see sth. could done better or safer feel free > to let me > > know. I like to learn and understand. > > > > Thanks in advance for your help and cooperation. > > > > CU all > > Joerg > > > > //-------------------------------------- > > // START OF CODE SNIPPET > > //-------------------------------------- > > > > void dom_TreeCleanup(DOMDocument *doc) > > { > > DOMNodeIterator *dni; > > DOMNode *nd, *tmpnd; > > DOMNamedNodeMap *attrs; > > DOMAttr *atnd; > > int type; > > > > // create Iterator > > dni = doc->createNodeIterator(doc->getDocumentElement(), > > DOMNodeFilter::SHOW_ALL, NULL, TRUE); > > > > // Fast forward to get the last node as the actual node > > while((tmpnd = dni->nextNode()) != NULL) > > nd = tmpnd; > > > > // Process the IteratorNodes backwards > > while(nd != NULL) > > { > > // Get the nodetype to decide what to do (different nodes > are handled > > differently) type = nd->getNodeType(); > > > > if(type == DOM_COMMENT_NODE) > > { > > // Don't need commentnodes anymore > > dom_RemoveNode(nd); > > } > > else if(type == DOM_ELEMENT_NODE) > > { > > // Aaaah! an Element Node. This needs attribute related > processing > > // so get the attributes for further investigation > > attrs = nd->getAttributes(); > > > > // if there are attributes -> research them > > if(attrs != NULL) > > { > > atnd = (DOMAttr *) attrs->getNamedItem(X(DOM_DEL_TAG)); > > if(atnd != NULL) > > { > > if(strcmp(X2C(atnd->getValue()), "1") == 0) > > { > > // If the delflag attribute value is 1 remove > > that node > > dom_RemoveNode(nd); > > } > > else > > { > > // If the delflag value is zero leave the node > > alone but > > // remove the delflag attributenode > > dom_RemoveAttr(atnd); > > } > > } > > } > > > > // General Cleanup that belongs to every type of node > > // If the actual node now (after nodetype-specific > > processing) don't have any > > // attributes AND no childnodes it is useless -> remove it > > if(!(nd->hasAttributes()) && !(nd->hasChildNodes())) > > { > > dom_RemoveNode(nd); > > } > > } > > > > // get the previous node as the new actual node > > nd = dni->previousNode(); > > } > > } > > > > void dom_RemoveNode(DOMNode *nd) > > { > > nd->getParentNode()->removeChild(nd); > > nd->release(); > > } > > > > void dom_RemoveAttr(DOMAttr *attr) > > { > > attr->getOwnerElement()->removeAttributeNode(attr); > > } > > > > //-------------------------------------- > > // END OF CODE SNIPPET > > //-------------------------------------- > > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > > > > > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
