Android: error in XML parsing with SAX - truncation of the text due to wrong "length" in "characters" void

StackOverflow https://stackoverflow.com/questions/21334353

  •  02-10-2022
  •  | 
  •  

Question

I'm using a SAX parser, and sometimes I have this problem: in the "characters" void the length is wrong (4 characters instead of 7), and I read only one part of my text.

Maybe somebody has an idea why I have this issue sometimes...

Thanks a lot!

Here is the section of the parsed XML file where I have the problem (the parsed "TagPosition" of the first element is "258" instead of "258 614" - all the rest if perfect!!):

XML

....
<LocationTag>
     <Tag>
          <TagID>#201401116505.1.1.2.1</TagID>
          <Zmin>0</Zmin>
          <TagPosition>258 614</TagPosition>
          <MotionNode>4</MotionNode>
          <TagPointRef>#201401116505.1.1.2</TagPointRef>
     </Tag>
     <Tag>
          <TagID>#201401116505.1.1.2.2</TagID>
          <Zmin>0</Zmin>
          <TagPosition>272 486</TagPosition>
          <MotionNode>1</MotionNode>
          <TagPointRef>#201401116505.1.1.2</TagPointRef>
     </Tag>
</LocationTag>
....

And my code:

public class EnvironmentDataParse extends DefaultHandler{

    String TAG = "XMLHelper";

    Boolean currTag = false;
    String currTagVal = "";
    private Boolean inTag = false;

    public void get() {
        try {       
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser mSaxParser = factory.newSAXParser();
            XMLReader mXmlReader = mSaxParser.getXMLReader();
            mXmlReader.setContentHandler(this);
            mXmlReader.parse(new InputSource(getResources().openRawResource(SharedValues.EnvirFile)));  //read xml from res folder
        } catch(Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if(currTag) {
            currTagVal = currTagVal + new String(ch, start, length);
            currTag = false;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        currTag = false;     
        float[] currTagVal_float;

    if(localName.equalsIgnoreCase("Boundary"))
            boundary.setBoundary(currTagVal);

        else if(localName.equalsIgnoreCase("MotionNode")){
            if (inTag) {locTag.setMotionNode(currTagVal);}
            else{point.setMotionNode(currTagVal);}
        }

        else if(localName.equalsIgnoreCase("Point"))
            placePoint.add(point);

        else if(localName.equalsIgnoreCase("TagID"))
            locTag.setTagID(currTagVal);

        else if(localName.equalsIgnoreCase("TagPosition"))
        {               
            Log.i(TAG, "TAG: " + localName);
                Log.i(TAG, "currTagVal: " + currTagVal);
            locTag.setTagPosition(currTagVal);}

        else if(localName.equalsIgnoreCase("TagPointRef"))
            locTag.setTagPointRef(currTagVal);

        else if(localName.equalsIgnoreCase("Tag"))
            locationTag.add(locTag);
        }

    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {


        currTag = true;
        currTagVal = "";
        if(localName.equals("head"))
            boundary = new BoundaryValue();

        else if(localName.equals("Tag")){
            inTag = true;
            locTag = new TagValue();}           
    }
}

The LogCat shows this ("258" instead of "258 614"):

01-24 14:24:46.512: D/dalvikvm(25652): Late-enabling CheckJNI
01-24 14:24:46.527: E/jdwp(25652): Failed sending reply to debugger: Broken pipe
01-24 14:24:46.527: D/dalvikvm(25652): Debugger has detached; object registry had 1 entries
01-24 14:24:46.647: I/XMLHelper(25652): TAG: TagPosition
01-24 14:24:46.647: I/XMLHelper(25652): currTagVal: 258 
01-24 14:24:46.652: I/XMLHelper(25652): TAG: TagPosition
01-24 14:24:46.652: I/XMLHelper(25652): currTagVal: 272 486
01-24 14:24:46.657: D/dalvikvm(25652): GC_CONCURRENT freed 185K, 8% free 3347K/3604K, paused 2ms+3ms, total 21ms
Was it helpful?

Solution

Your characters method is setup to only collect on the first call.

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    if(currTag) {
        currTagVal = currTagVal + new String(ch, start, length);
        currTag = false;
    }
}

The line

        currTag = false;

is preventing the characters method from collecting all the data. It is never guaranteed to all show up together, and this code makes later calls to this method do nothing.

In fact I suspect you don't need the currTag field at all, as it is only used as the if condition in this method, and is set true in startElement and false in endElement.

You can likely reduce this method to

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    currTagVal = currTagVal + new String(ch, start, length);
}

OTHER TIPS

 @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {


        currTag = true;
        currTagVal = "";
        if(localName.equals("LocationTag"))
            boundary = new BoundaryValue();

        else if(localName.equals("Tag")){
            inTag = true;
            locTag = new TagValue();}           
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top