Android SAXParser Leftovers
-
30-06-2021 - |
Domanda
I have an Android app that parses XML using SAXParser. Everything goes ok, excepting some texts that get duplicated and trimmed. For example: "Just do it, even if you do not know how!" becomes " not know how!"
This is the DefaultHandler code. 10x!
DefaultHandler handler = new DefaultHandler()
{
Praise praise;
String elementValue = null;
Boolean elementOn = false;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
if (localName.equals("praise"))
{
praise = new Praise();
elementOn = true;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
// elementOn = false;
if (localName.equals("PRAISE_TEXT"))
{
praise.setPraiseText(elementValue);
}
if (localName.equals("MOOD"))
{
praise.setMood(elementValue);
}
if (localName.equals("RATING"))
{
praise.setRating(Integer.valueOf(elementValue));
}
if (localName.equals("praise"))
{
elementOn = false;
if (update)
{
if (database.getPraiseByText(praise.getPraiseText(), db) == null)
{
database.addPraise(db, praise.getPraiseText(), praise.getMood(),
Integer.valueOf(praise.getRating()));
}
}
else
database.addPraise(db, praise.getPraiseText(), praise.getMood(),
Integer.valueOf(praise.getRating()));
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
// StringBuffer b = new StringBuffer();
if (elementOn)
{
elementValue = new String(ch, start, length);}}};
Soluzione
In SaxParsing, you do not have guarantee that characters
will be called only once!
For this, you should concatenate all the characters you receive withing the same element
This is a just your code with a small modification. You should use StringBuilder
instead of using String (:
DefaultHandler handler = new DefaultHandler()
{
Praise praise;
String elementValue = null;
Boolean elementOn = false;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
elementValue = new String();
if (localName.equals("praise"))
{
praise = new Praise();
elementOn = true;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (localName.equals("PRAISE_TEXT"))
{
praise.setPraiseText(elementValue);
}
if (localName.equals("MOOD"))
{
praise.setMood(elementValue);
}
if (localName.equals("RATING"))
{
praise.setRating(Integer.valueOf(elementValue));
}
if (localName.equals("praise"))
{
elementOn = false;
if (update)
{
if (database.getPraiseByText(praise.getPraiseText(), db) == null)
{
database.addPraise(db, praise.getPraiseText(), praise.getMood(),
Integer.valueOf(praise.getRating()));
}
}
else
database.addPraise(db, praise.getPraiseText(), praise.getMood(),
Integer.valueOf(praise.getRating()));
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
// StringBuffer b = new StringBuffer();
if (elementOn)
{
elementValue = elementValue + new String(ch, start, length);
}
}
};
Altri suggerimenti
This problem often comes in SaxParsing. The Actual problem is it breaks the String by "/n" & only last part of String is available for us. Now come to the solution, Take different booleans for tags(containing problems or for all).
In startElement method make relevent boolean true.
if (localName.equals("PRAISE_TEXT"))
{
isPrase= true'
praise.setPraiseText(elementValue);
}
in endElemet method make relevent boolean false.
if (localName.equals("PRAISE_TEXT"))
{
isPrase= false;
praise.setPraiseText(elementValue);
}
in characters method check for boolean like this:
if(isPrase)
{
elementValue = new String(ch, start, length);}}};
}