xml-general mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mike Tang <M...@seagreentech.com>
Subject RE: Bug
Date Thu, 09 Nov 2000 16:44:43 GMT
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)
5 
 
 
Fifth time through the loop
5  Remove (1)
 
Hope this clarifies it.
 
Mike Tang
Seagreen Technologies, Inc
mike@seagreentech.com <mailto:mike@seagreentech.com> 
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  <mailto:Mike@seagreentech.com> Tang 
To: 'dfoster@equitytg.com' <mailto:'dfoster@equitytg.com'>  
Cc: general@xml.apache.org <mailto: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 <mailto: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


Mime
View raw message