File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes XML and Related Technologies and the fly likes problem in parsing an XML using SAX parser. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » XML and Related Technologies
Bookmark "problem in parsing an XML using SAX parser." Watch "problem in parsing an XML using SAX parser." New topic
Author

problem in parsing an XML using SAX parser.

Pooja Agarwal
Ranch Hand

Joined: May 19, 2004
Posts: 37
Hai All,

I have got a problem in parsing an XML using SAX parser.

I have an XML (sample below) which need to be parsed
----------------------------------------------------
<line-items>

<item num="1">
<part-number>PN1234</part-number>
<quantity uom="ea">10</quantity>
<lpn>LPN1060</lpn>
<reference num="1">Line ref 1</reference>
<reference num="2">Line ref 2</reference>
<reference num="3">Line ref 3</reference>
</item>
<item num="2">
<part-number>PN1527</part-number>
<quantity uom="lbs">5</quantity>
<lpn>LPN2152</lpn>
<reference num="1">Line ref 1</reference>
<reference num="2">Line ref 2</reference>
<reference num="3">Line ref 3</reference>
</item>
.
.
.
.
<item num="n">
.........
.........
.........
.........
</item>

</line-items>

There can be any number of items( 1 to n). I need to parse these

item values using SAX parser and invoke a stored procedure for

each item with its

values(partnumber,qty,lpn,refnum1,refnum2,refnum3).

Suppose if there are 100 items, i need to invoke the stored

procedure sp1() 100 times for each item.

I need to invoke the stored procedure in endDocument() method of

SAX event handler and not in endelement() method.

What is the best way to store those values and invoke the stored

procedure in enddocument() method.

Any help would br greatly appreciated.
Thanks in advance
Pooja.
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Here's something to start with -- something that hopefully illustrates how you typically "populate" objects using a SAX handler:


Author of Test Driven (2007) and Effective Unit Testing (2013) [Blog] [HowToAskQuestionsOnJavaRanch]
Pooja Agarwal
Ranch Hand

Joined: May 19, 2004
Posts: 37
Hai Lasse,

Thanks for ur reply.
Its a good approach.
Thanks once again.

Pooja.
Pooja Agarwal
Ranch Hand

Joined: May 19, 2004
Posts: 37
Lasse Koskela

I have tried using ur code
but there is no class Item, which u r trying to use in ur code.
let me know what exactly should be there.

thanks once again
Pooja.
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Originally posted by Pooja Agarwal:
I have tried using ur code but there is no class Item, which u r trying to use in ur code.

That was just an example. Obviously you need to write your own classes to match whatever entities your XML document logically represents.
Pooja Agarwal
Ranch Hand

Joined: May 19, 2004
Posts: 37
Hai

I have written following code inorder to parse and print the values with out creating another class.
Its compiling fine but throwing a runtime eroor.
Java.Lang.ClassCastException:

The Code is
-----------
import java.io.*;
import java.util.*;
import org.xml.sax.*;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderAdapter;

public class parselineitems extends DefaultHandler
{
private List items;
private List currentItem;
//private Item temp;

StringBuffer accumulator;
static private Writer out;
String localRoot = new String();
int i;
String temp;

public static void main(String args[])
{

try
{
XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.crimson.parser.XMLReaderImpl");
DefaultHandler handler = new parselineitems();
parser.setContentHandler(handler);
parser.parse(args[0]);
}
catch (Exception e)
{
System.err.println(e);
}

}


public void startDocument() throws SAXException
{
accumulator = new StringBuffer();
this.items = new ArrayList();
}

public void startElement(String namespaceURI, String localName,
String qualifiedName, Attributes atts) throws SAXException
{
accumulator.setLength(0);
if(localName.equals("item"))
{
this.currentItem = new ArrayList();
}
else
{

}
}

public void characters(char[] text, int start, int length) throws SAXException
{
accumulator.append(text, start, length);
}

public void endElement(String namespaceURI, String localName,
String qualifiedName) throws SAXException
{
if (localName.equals("item"))
{
// we're done with the item, add it to the list
this.items.add(this.currentItem);
}
else if (localName.equals("part-number"))
{
this.currentItem.add(accumulator);
}
else if (localName.equals("quantity"))
{
this.currentItem.add(accumulator);
}
else if (localName.equals("lpn"))
{
this.currentItem.add(accumulator);
}
else if (localName.equals("reference"))
{
this.currentItem.add(accumulator);
}
}

public void endDocument() throws SAXException
{

for (i=0;i<=items.size();i++)
{
List temp2 = new ArrayList();
temp2 = (ArrayList)items.get(i);
for (i=0;i<=temp2.size();i++)
{
temp = (String)temp2.get(i);
System.out.println(" The value of elements" + temp);
}
System.out.println(" ");
}

}
}
---------------------------------------
can u let me know where i went wrong.

Thanks a lot for all ur help.
I appreciate ur help.
Pooja.
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Apparently your ClassCastException comes from this piece of code:

For some reason, your 'items' variable is an ArrayList of ArrayLists. In this loop, you're trying to cast the inner ArrayList instances into String...

PS. I'd suggest using the Iterator (List#iterator()) instead of a for loop. It's a lot cleaner that way.

PPS. I'd suggest using UBB [CODE][/CODE] tags for all code snippets to preserve formatting (see the difference between my snippet above and your snippets).
Pooja Agarwal
Ranch Hand

Joined: May 19, 2004
Posts: 37
Hai Lasse Koskela ,

Thanks a lot for ur patience in looking into my code.
I really appreciate ur patience.
I am very sorry for not including the code tags.
I have tried to overcome the classcast exception. But got into a new problem.
When i try to execute my program only the last value is getting printed. i am unable to trace it out.

My code is as below.
-------------------


The XML which i am using.

the problem is that its displaying the last tag value all the time. You can just copy the code and try executing the code.
Thanks a lot for taking ur time.
Pooja
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Inside endElement(), when you do

you're not adding the string inside 'accumulator' into the list -- you're adding a reference to the StringBuffer object into the list. Now, in endDocument() you iterate through the list and it contains X number of references to the same StringBuffer object. The reason why you're seeing just the "last element" is that that's what you've last populated the StringBuffer object with.

If you just want to get one step further with your task, try adding ".toString()" to the add() calls inside your endElement() method.

Some further tips:
- Create an 'Item' or 'LineItem' class and use that instead of Vectors. It makes the code a lot easier to read
- Use meaningful variable names instead of "temp", "temp2", etc.
Pooja Agarwal
Ranch Hand

Joined: May 19, 2004
Posts: 37
Hai

That was a stupid mistake(passing the ref) i was doing.
uumm that was really bad on my part.

Its working fine now after using tostring and trim methods.
I am really very thankful to u and i spent whole day to fix the things around. Still got to use the class as u've said. and the variable names, yes i need to change that to.

Thanks a lot for all ur help and suggestions.
I really appreciate ur patience.
Thanks once again.
Pooja.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: problem in parsing an XML using SAX parser.