I'm having a problem using the SAX parser to parse a very simple XML file on different Android releases.
Using a Motorola XT316 with Android 2.3.3 the code works fine. I can see that it enters on all the tags. But when using a PanDigital with Android 2.1 the code doesn't work. It opens the XML file correctly but it doesn't enter in any tags.
The code of the parser:
public MyParser(Context context ) {
super();
theContext=context;
getData();
}
//start of the XML document
@Override
public void startDocument () {
Log.d("DataHandler", "Start of XML document");
}
//end of the XML document
@Override
public void endDocument () { Log.d("DataHandler", "End of XML document"); }
//opening element tag
@Override
public void startElement (String uri, String name, String qName, Attributes atts)
{
if(qName.equals("ARQUIVO"))
{
Log.d("DataHandler", "Start of ARQUIVO");
}
}
//closing element tag
@Override
public void endElement (String uri, String name, String qName)
{
if(qName.equals("ARQUIVO"))
{
Log.d("DataHandler", "End of ARQUIVO");
}
}
//element content
public void characters (char ch[], int start, int length)
{
}
public void getData()
{
//take care of SAX, input and parsing errors
try
{
//set the parsing driver
System.setProperty("org.xml.sax.driver","org.xmlpull.v1.sax2.Driver");
//create a parser
SAXParserFactory parseFactory = SAXParserFactory.newInstance();
parseFactory.setNamespaceAware(true);
SAXParser xmlParser = parseFactory.newSAXParser();
//get an XML reader
XMLReader xmlIn = xmlParser.getXMLReader();
//instruct the app to use this object as the handler
xmlIn.setContentHandler(this);
InputStreamReader xmlStream = new InputStreamReader(theContext.getResources().openRawResource(R.raw.arquivos));
//build a buffered reader
BufferedReader xmlBuff = new BufferedReader(xmlStream);
xmlIn.parse(new InputSource(xmlBuff));
}
catch(SAXException se) {
Log.e("AndroidTestsActivity","SAX Error " + se.getMessage());
}
catch(IOException ie) {
Log.e("AndroidTestsActivity","Input Error " + ie.getMessage());
}
catch(Exception oe) {
Log.e("AndroidTestsActivity","Unspecified Error " + oe.getMessage());
}
}
}
The XML file:
<?xml version="1.0" encoding="UTF-8"?>
<ARQUIVOS>
<ARQUIVO
arquivo_caminho="http://192.168.0.60:8099/screen.xml"
arquivo_nome="screen.xml" />
<ARQUIVO
arquivo_caminho="http://192.168.0.60:8099/Images/T_0.png"
arquivo_nome="T_0.png" />
<ARQUIVO
arquivo_caminho="http://192.168.0.60:8099/Images/T_1.png"
arquivo_nome="T_1.png" />
<ARQUIVO
arquivo_caminho="http://192.168.0.60:8099/Images/T_2.png"
arquivo_nome="T_2.png" />
<ARQUIVO
arquivo_caminho="http://192.168.0.60:8099/Images/T_3.png"
arquivo_nome="T_3.png" />
<ARQUIVO
arquivo_caminho="http://192.168.0.60:8099/Images/T_4.png"
arquivo_nome="T_4.png" />
</ARQUIVOS>
I can see it shows the message "Start of XML document" and "End of XML document" but it doesn't show the message "Start of ARQUIVO" and "End of ARQUIVO" between them.
I don't know why this is happening and can't fix it. Any help will be appreciated.
Thanks in advance.
This link helped me to solve the problem code.google.com/p/android/issues/detail?id=11223
Apparently there is a difference on the of functionality on the SAX parser between android 2.1 and the newer versions. It puts the tag of the element on different parameters. I don't know if it is a bug but it certainly looks like one.
The way to make it work is to change the functions startElement and endElement.The are implemented below.
public static String getCorrectName(String qName, String name) {//used to fix bug from the sax on version 2.1
String _retValue = null;
if (Build.VERSION.SDK_INT<=7) _retValue = localName;
else _retValue = qName;
return _retValue;
}
//opening element tag
@Override
public void startElement (String uri, String name, String qName, Attributes atts)
{
String corretcName=getCorrectName(qName, name);
if(corretcName.equals("ARQUIVO"))
{
Log.d("DataHandler", "Start of ARQUIVO");
}
}
//closing element tag
@Override
public void endElement (String uri, String name, String qName)
{
String corretcName=getCorrectName(qName, name);
if(corretcName.equals("ARQUIVO"))
{
Log.d("DataHandler", "End of ARQUIVO");
}
}