Dane,
 
You are taking the getLength() before you go into the loop.  This will return 5.  This is correct at the time.  What is happening is that when you remove the first node, the getLength() should then return 4.  You are never reinitializing the value of the counter to reflect this. You are then removing nodes based upon the counters value (which will loop to five). When you go to remove the 4th node there are only 2 nodes avaliable (check the value of getLength() each time through the loop) causing the null error to occur.  In the following example the number in the ( ) indicates the counter value:
 
First time through the loop
1   Remove (1) 
2
3
4
5
 
Second time through the loop
2
3    Remove (2)
4
5
 
 
Third time through the loop
2
4
5   Remove (3)
 
 
Fourth time through the loop
2
4
.
.    Remove (4)
 
You can see that the counter has moved beyond the amount of items remaining in the node list.  This results in the what you were seeing in the second example
 
        <parent1>
            <child>I am Bobby 3</child>      ====> the second item in the list
            <child>I am Bobby 1</child>      ====> the fourth item in the list
        </parent1>
 
 
By setting the removeChild() index to 1, the children will all be removed.  The number in the ( ) represents the hardcoded value to 1.
 
First time through the loop
1   Remove (1) 
2
3
4
5
 
Second time through the loop
2   Remove (1)
3   
4
5
 
 
Third time through the loop
3   Remove (1)
4
5  
 
 
Fourth time through the loop
4   Remove (1)
 
 
Fifth time through the loop
5  Remove (1)
 
Hope this clarifies it.
 
Mike Tang
Seagreen Technologies, Inc
888-372-2221
It you said doesn't work because of the following:  The for-loop that removes the nodes are constrained by the number of nodes that nodes.getLength() return.  Therefore, it's impossible for the loop to continue beyond the number of nodes that actually exist, unless nodes.getLength() is returning an incorrect number of nodes.  If you've noticed, I specifically stated where in the loop the NullPointerException gets thrown.  It's not at the end.  I know this because I've watched the code execute in my debugger.
 
This is what's supposed to happen
i = 0
    Remove first node,    4 nodes left
i = 1
    Remove second node,   3 nodes left
i = 2
    Remove third node,    2 nodes left
i = 3
    Remove fourth node,   1 node left
i = 4
    Remove fifth node,    0 nodes left
exit for-loop
 
This is what happens what actually happens
i = 0
    Remove first node,        4 nodes left
i = 1
    Remove second node,       3 nodes left
i = 2
    Remove third node,        2 nodes left
i = 3
    item.( i ) return null,   2 nodes left
i = 4
    item.( i ) return null,   2 nodes left
exit for-loop
 
Dane
----- Original Message -----
From: Mike Tang
To: 'dfoster@equitytg.com'
Cc: general@xml.apache.org
Sent: Thursday, November 09, 2000 9:55 AM
Subject: RE: Bug

Dane,   
    I believe what you are runnning into is that your counter is incrementig past the amount of nodes that have not been removed.
 
    for example
        I = 1
                Remove the first node,         4 nodes left
        I = 2
                Remove the second node,   3 nodes left
        I = 3
                Remove the third node,       2 nodes left
        i = 4
                with only two nodes left, there is no way to remove the fourth node
 
Try the following change to line 18
        if( Node.ELEMENT_NODE == currentNode.getNodeType() ) parentNode.removeChild( 1 );   
      
 
Hope this helps,
 
Mike Tang
Seagreen Technologies, Inc
mike@seagreentech.com
888-372-2221
-----Original Message-----
From: Dane Foster [mailto:dfoster@equitytg.com]
Sent: Wednesday, November 08, 2000 10:22 PM
To: general@xml.apache.org
Subject: Bug

I think I may have found a bug in Xerces.  My info is as follows:
 
=================================================================================
Platform:            Windows NT V4.0 Svc Pak 6a
 
Machine Spec:        Dell Precision 210
                     RAM 384MB
                     Processor Intel Pentium III 600MHZ
 
JDK:                 Sun SDK 1.3.0 Hotspot Client VM (build 1.3.0-C, mixed mode)
 
IDE:                 Borland JBuilder 3.5
 
Xerces Type:         Xerces-J
 
Xerces Version:      1.2.1
===================================================================================
 
Here is the XML Document as it exist in memory (DOM);
 
<rootElement>
    <parent1>
        <child>I am Bobby 4</child>
        <child>I am Bobby 3</child>
        <child>I am Bobby 2</child>
        <child>I am Bobby 1</child>
        <child>I am Bobby 0</child>
    </parent1>
    <parent2>I do not have any children of my own</parent2>
</rootElement>
 
 
What I'm trying to accomplish is removing all the children of 'parent1', while leaving 'parent1' in tact.  Example:
 
<rootElement>
    <parent1/><!--No children-->
    <parent2>I do not have any children of my own</parent2>
</rootElement>
 
 
 
There are two versions to my code.  One causes a NullPointerException and the other leaves two children.  I will clarify in a second.  The first code follows:
 
/* Version 1 */
 
// Standard Java Libraries
import java.io.*;
// XML Libraries
import org.xml.sax.*;
import org.w3c.dom.*;
import org.w3c.dom.traversal.*;
import org.apache.xerces.dom.*;
import org.xml.sax.SAXException;
import org.apache.xml.serialize.*;
import org.apache.xerces.parsers.*;
import org.xml.sax.helpers.DefaultHandler;
 
 
public class Testing
{
    public static void main( String args[] )
    {
        Document doc = new DocumentImpl();                                                   // line 1
 
        Element rootElement = doc.createElement( "rootElement" );                             // line 2
 
        Element parent1 = doc.createElement( "parent1" );                                     // line 3
        Element parent2 = doc.createElement( "parent2" );                                     // line 4
 
        for( int i = 5; i-- > 0; )                                                            // line 5                                    
        {
            Element child = doc.createElement( "child" );                                     // line 6
            child.appendChild( doc.createTextNode( "I am Bobby " + i ) );                     // line 7
            parent1.appendChild( child );
        }
 
        parent2.appendChild( doc.createTextNode( "I do not have any children of my own" ) );  // line 8
 
        rootElement.appendChild( parent1 );                                                   // line 9
        rootElement.appendChild( parent2 );                                                   // line 10
        doc.appendChild( rootElement );                                                       // line 11
 
        /* From here on pretend the above variables (except doc) are not accessible so I must access the DOM starting at the root*/
        
        /* This is where more program really starts.*/
        NodeList nodes = doc.getDocumentElement().getElementsByTagName( "parent1" );          // line 12
        Node parentNode = nodes.item( 0 );                                                    // line 13
        nodes = parentNode.getChildNodes();                                                   // line 14
        int length = nodes.getLength();                                                       // line 15
        for( int i = 0; i < length; i++ )                                                     // line 16
        {
            Node currentNode = nodes.item( i );                                               // line 17
            if( Node.ELEMENT_NODE == currentNode.getNodeType() ) parentNode.removeChild( currentNode );    // line 18
        }
        try
        {
            XMLSerializer serializer = new XMLSerializer( System.out, new OutputFormat( "XML", "UTF-8", true ) );// line 19
            serializer.serialize( doc );                                                        // line 20
        }
        catch( Exception e )                                                                    // line 21
        {
            System.out.println( e.getMessage() );                                               // line 22
            e.printStackTrace();                                                                // line 23
        }
        System.exit( 0 );                                                                       // line 24
    }
}
Version 1 fails on the fourth (0 -> 3 )iteration of the for-loop (line 16) with a NullPointerException.
 
/*Version 2*/
 
// Standard Java Libraries
import java.io.*;
// XML Libraries
import org.xml.sax.*;
import org.w3c.dom.*;
import org.w3c.dom.traversal.*;
import org.apache.xerces.dom.*;
import org.xml.sax.SAXException;
import org.apache.xml.serialize.*;
import org.apache.xerces.parsers.*;
import org.xml.sax.helpers.DefaultHandler;
 
public class Testing
{
    public static void main( String args[] )
    {
        Document doc = new DocumentImpl();
 
        Element rootElement = doc.createElement( "rootElement" );
 
        Element parent1 = doc.createElement( "parent1" );
        Element parent2 = doc.createElement( "parent2" );
 
        for( int i = 5; i-- > 0; )
        {
            Element child = doc.createElement( "child" );
            child.appendChild( doc.createTextNode( "I am Bobby " + i ) );
            parent1.appendChild( child );
        }
 
        parent2.appendChild( doc.createTextNode( "I do not have any children of my own" ) );
 
        rootElement.appendChild( parent1 );
        rootElement.appendChild( parent2 );
        doc.appendChild( rootElement );
 
        /* From here on pretend the above variables (except doc) are not accessible so I must access the DOM starting at the root*/
        
        /* This is where more program really starts.*/

        NodeList nodes = doc.getDocumentElement().getElementsByTagName( "parent1" );
        Node parentNode = nodes.item( 0 );
 
        nodes = parentNode.getChildNodes();
        int length = nodes.getLength();
        for( int i = 0; i < length; i++ )
        {
            Node currentNode = nodes.item( i );
            if( null!= currentNode && null != currentNode && Node.ELEMENT_NODE == currentNode.getNodeType() ) parentNode.removeChild( currentNode );
           /*The above is where Version 1 differs from Version 2.  I've added the check for null in the if statement ( null != currentNode )*/
        }
        try
        {
            XMLSerializer serializer = new XMLSerializer( System.out, new OutputFormat( "XML", "UTF-8", true ) );
            serializer.serialize( doc );
        }
        catch( Exception e )
        {
            System.out.println( e.getMessage() );
            e.printStackTrace();
        }
        System.exit( 0 );
    }
}
 
This is the result when Version 2 executes:
<?xml version="1.0" encoding="UTF-8"?>
<rootElement>
    <parent1>
        <child>I am Bobby 3</child>
        <child>I am Bobby 1</child>
    </parent1>
    <parent2>I do not have any children of my own</parent2>
</rootElement>
 
 
I became aware of this problem when a servlet I am working on kept throwing the NullPointerException.  I've written the above to simulate exactly what happens in the servlet.  I write my code on NT but it gets executed on Linux (shouldn't make a difference).  My Linux configuration is as follows:
 
=================================================================================
Platform:            Linux Mandrake 7.0 Kernel 2.2.15
 
Machine Spec:        Dell PowerEdge 1300
                     256MB RAM
                     Dual Intel Pentium II 450 MHZ
 
JDK:                 IBM Java 1.3 SDK for Linux w/ JIT and Native Threads
 
Xerces Type:         Xerces-J
 
Xerces Version:      1.2.1
===================================================================================
 
 
Dane Foster