You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@xml.apache.org by Dane Foster <df...@equitytg.com> on 2000/11/09 04:21:59 UTC

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