Why SAX parser reads truncated data ?

S

Sanjeev

Dear Gurus,

I m using SAX parser for reading XML file. Java code is as follows.

package ivr.bank.util;
import javax.xml.parsers.*;
.......
.......
public class CustomerIFXParser extends DefaultHandler{
CustomerDetailCollectionVO customerDetailCollectionVO;
Vector linkedAccountList;
private String tempVal;
private CustomerDetailVO customerDetailVO;
private LinkedAccountVO linkedAccountVO;
private String accountFlag = "";
public CustomerIFXParser(){
customerDetailCollectionVO = new
CustomerDetailCollectionVO();
linkedAccountList = new Vector();
}
public CustomerDetailCollectionVO runExample(String receivedMessage)
{
parseDocument(receivedMessage);
customerDetailVO.setLinkedAccountList(linkedAccountList);

customerDetailCollectionVO.add(customerDetailVO);
return customerDetailCollectionVO;
}
private void parseDocument(String receivedMessage) {
SAXParserFactory spf = SAXParserFactory.newInstance();
try {
SAXParser sp = spf.newSAXParser();
sp.parse("E:\\CustProf.xml",
this);
}catch(Exception se) {
}
}
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
tempVal = "";
if(qName.equalsIgnoreCase("PartyAcctRelInqRs")) {
linkedAccountVO = new LinkedAccountVO();
}else if(qName.equalsIgnoreCase("BaseSvcRs")) {
customerDetailVO = new CustomerDetailVO();
}
}
public void characters(char[] ch, int start, int length) throws
SAXException {
tempVal = new String(ch,start,length);
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(qName.equalsIgnoreCase("AcctId")) {
linkedAccountVO.setAccountNo(tempVal);
}else if(qName.equalsIgnoreCase("SCB_AcctFlagType")) {
accountFlag = tempVal;
}else if (qName.equalsIgnoreCase("SCB_AcctFlagValue") &&
accountFlag.equalsIgnoreCase("AllowPBFT")) {
linkedAccountVO.setAllowPBFT(tempVal);
}else if (qName.equalsIgnoreCase("SCB_OpenDt")) {
linkedAccountVO.setAccountOpenDate(tempVal);
}else if (qName.equalsIgnoreCase("BirthDt")) {
linkedAccountVO.setDob(tempVal);
}else if (qName.equalsIgnoreCase("Addr")) {
linkedAccountVO.setAddr1(tempVal);
}
}
}


XML content as follows i.e. It shows records of 5 accounts as follows

<root>
<PartyAcctRelInqRs>
<AcctId>22505989359</AcctId>
<SCB_AcctFlag>
<SCB_AcctFlagType>DealFlag</SCB_AcctFlagType>
<SCB_AcctFlagValue>N</SCB_AcctFlagValue>
</SCB_AcctFlag>
<SCB_AcctFlag>
<SCB_AcctFlagType>LinkedAccountFlag</SCB_AcctFlagType>
<SCB_AcctFlagValue>N</SCB_AcctFlagValue>
</SCB_AcctFlag>
<SCB_OpenDt>2008-03-15</SCB_OpenDt>
<BirthDt>1998-08-06</BirthDt>
<Addr>6</Addr>
</PartyAcctRelInqRs>
<PartyAcctRelInqRs>
<AcctId>22505989350</AcctId>
..........
..........
</PartyAcctRelInqRs>
<PartyAcctRelInqRs>
<AcctId>22505989351</AcctId>
..........
..........
</PartyAcctRelInqRs>
<PartyAcctRelInqRs>
<AcctId>22505989352</AcctId>
<SCB_AcctFlag>
<SCB_AcctFlagType>DealFlag</SCB_AcctFlagType>
<SCB_AcctFlagValue>N</SCB_AcctFlagValue>
</SCB_AcctFlag>
<SCB_AcctFlag>
<SCB_AcctFlagType>LinkedAccountFlag</SCB_AcctFlagType>
<SCB_AcctFlagValue>N</SCB_AcctFlagValue>
</SCB_AcctFlag>
<SCB_OpenDt>2008-03-15</SCB_OpenDt>
<BirthDt>1998-08-06</BirthDt>
<Addr>6</Addr>
</PartyAcctRelInqRs>
<PartyAcctRelInqRs>
<AcctId>22505989353</AcctId>
..........
..........
</PartyAcctRelInqRs>
</root>

In XML file there are 2 types of flag namely "LinkedAccountFlag" and
"AllowPBFT"
Since in XML file it is given like below

<SCB_AcctFlagType>LinkedAccountFlag</SCB_AcctFlagType>
<SCB_AcctFlagValue>N</SCB_AcctFlagValue>
<SCB_AcctFlagType>AllowPBFT</SCB_AcctFlagType>
<SCB_AcctFlagValue>Y</SCB_AcctFlagValue>

so i m using if statement like below

if (qName.equalsIgnoreCase("SCB_AcctFlagValue") &&
accountFlag.equalsIgnoreCase("LinkedAccountFlag")) {
linkedAccountVO.setAllowPBFT(tempVal);
}else if (qName.equalsIgnoreCase("SCB_AcctFlagValue") &&
accountFlag.equalsIgnoreCase("AllowPBFT")) {
linkedAccountVO.setAllowPBFT(tempVal);
}

I am not able to read LinkedAccountFlag value for 4 th record.
(22505989352) i.e. N
I have checked SCB_AcctFlagType tag for 4 th record is
"LinkedAccountFlag" in xml file, but my parser is reading as "tFlag".

It is not problem with another accounts.
Why parser is truncating the string from "LinkedAccountFlag" to
"tFlag" while reading.

Could anyone help me in above.

Thanking in advance.

Regards
Sanjeev
 
T

Thomas Kellerer

Sanjeev, 18.08.2008 09:10:
Dear Gurus,

I m using SAX parser for reading XML file. Java code is as follows.
[...]
In XML file there are 2 types of flag namely "LinkedAccountFlag" and
"AllowPBFT"
Since in XML file it is given like below

<SCB_AcctFlagType>LinkedAccountFlag</SCB_AcctFlagType>
<SCB_AcctFlagValue>N</SCB_AcctFlagValue>
<SCB_AcctFlagType>AllowPBFT</SCB_AcctFlagType>
<SCB_AcctFlagValue>Y</SCB_AcctFlagValue>

so i m using if statement like below

if (qName.equalsIgnoreCase("SCB_AcctFlagValue") &&
accountFlag.equalsIgnoreCase("LinkedAccountFlag")) {
linkedAccountVO.setAllowPBFT(tempVal);
}else if (qName.equalsIgnoreCase("SCB_AcctFlagValue") &&
accountFlag.equalsIgnoreCase("AllowPBFT")) {
linkedAccountVO.setAllowPBFT(tempVal);
}

I am not able to read LinkedAccountFlag value for 4 th record.
(22505989352) i.e. N
I have checked SCB_AcctFlagType tag for 4 th record is
"LinkedAccountFlag" in xml file, but my parser is reading as "tFlag".

It is not problem with another accounts.
Why parser is truncating the string from "LinkedAccountFlag" to
"tFlag" while reading.

This sounds like this issue:

http://bugs.sun.com/view_bug.do?bug_id=6716312

When I hit this issue, it often was enough to simply save the XML file e.g. with a different line ending, or add an empty line at the beginning.

Regards
Thomas
 
M

Mike Schilling

characters() is not guaranteed to return of all the characters in a
single call. From the Javadoc:

The Parser will call this method to report each chunk of character
data. SAX
parsers may return all contiguous character data in a single
chunk, or they may
split it into several chunks

You need to append the characters returned in all of the calls,
something like:

private StringBuffer tempValue = new StringBuffer();

startElement()
{
tempValue.setLength(0); //clear buffer
...
}

characters(characters(char[] ch, int start, int length)
{
tempValue.append(ch, start, length); // append to buffer
}

endElement()
{
String value = tempValue.toString(); // use characters in
buffer
...
}
 
T

Thomas Kellerer

Mike Schilling, 18.08.2008 10:25:
characters() is not guaranteed to return of all the characters in a
single call.

Yes, but it should never return parts of the tag, which it does sometimes.
See http://bugs.sun.com/view_bug.do?bug_id=6716312

In the OPs post it's not clear which situation is occuring because the partial "tFlag" could be the value of the tag or the name of the tag.
In my case which was the cause for the above mentioned issue, characters() did return a part of the tag name not the value.

Thomas
 
M

Mike Schilling

Thomas said:
Mike Schilling, 18.08.2008 10:25:

Yes, but it should never return parts of the tag, which it does
sometimes. See http://bugs.sun.com/view_bug.do?bug_id=6716312

In the OPs post it's not clear which situation is occuring because
the partial "tFlag" could be the value of the tag or the name of the
tag. In my case which was the cause for the above mentioned issue,
characters() did return a part of the tag name not the value.


It could be either problem. Since the code that the OP supplied could
fail even without the bug you reference, fixing that problem is the
place to start.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top