Issue while reading from XML file on sdcard - android

Friends, I am facing an issue while reading information from a xml file located on the SD card.The code is being implemented successfully but there is nothing being displayed either on logcat nor there is no exception popping out. Please help me for the same.
public class History extends Activity
{
private ListView lstv;
static ArrayList<Records> arr;
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
setContentView(R.layout.history);
try {
String path = Environment.getExternalStorageDirectory()+"/saved_images/history.xml";
File file = new File(path);
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser=factory.newSAXParser();
XMLReader reader=parser.getXMLReader();
XMLHandler handler=new XMLHandler();
//parser.parse(stream,handler);
reader.parse(new InputSource(new InputStreamReader(new FileInputStream(file))));
arr=handler.getArray();
ArrayAdapter<Records> adpt=new ArrayAdapter<Records>(this, android.R.layout.simple_list_item_1,arr);
//lstv.setAdapter(adpt);
handler.startDocument();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
class XMLHandler extends DefaultHandler {
ArrayList<Records> array;
Records records ;
String strCurrentValue = null;
public ArrayList<Records> getArray() {
return array;
}
#Override
public void startDocument() throws SAXException {
super.startDocument();
array=new ArrayList<Records>();
}
#Override
public void startElement(String uri, String elementName, String qName,Attributes attributes) throws SAXException {
super.startElement(uri, elementName, qName, attributes);
if(elementName.equals("Record"))
{
records=new Records();
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
strCurrentValue=new String(ch, start, length);
}
#Override
public void endElement(String uri, String elementName, String qName)
throws SAXException {
super.endElement(uri, elementName, qName);
if(elementName.equals("date"))
{
records.date=strCurrentValue;
}else if(elementName.equals("cc"))
{
records.cc=strCurrentValue;
}
}
#Override
public void endDocument() throws SAXException {
super.endDocument();
for(Records c:array)
{
Log.d("XmlHandler", c.toString());
}
}
}
}
I am unable to see anything on log-cat or onto the screen. Please help me for the same code using snippets.
Thanks

It seems to me that your handler never actually adds the record to the array - looks like you need to include an action for the endElement of type 'Record' which adds it to the array.
Also as Giovanni says this entire piece of code will hold up the UI thread so if the XML file is non-trivial this should be handled in a separate thread with a progress dialog.

Related

How to parse xml data using SAX Parser and show it in listview

I want to parse XML data using SAX Parser and show the parsed data in the listview.
The XML is given below:-
<?xml version="1.0" encoding="UTF-8"?>
<category>
<category_info>
<parent_title>Shop</parent_title>
<parent_id>3</parent_id>
<has_more_items>0</has_more_items>
</category_info>
<items>
<item>
<label>Citrus</label>
<entity_id>130</entity_id>
<next>4</next>
<subcategory>0</subcategory>
<content_type>products</content_type>
<parent_id>128</parent_id>
<icon>http://foakh.com/media/catalog/category/cache/11/thumbnail/100x/9df78eab33525d08d6e5fb8d27136e95/yyyy.jpg</icon>
</item>
<item>
<label>Apples</label>
<entity_id>131</entity_id>
<next>3</next>
<subcategory>0</subcategory>
<content_type>products</content_type>
<parent_id>128</parent_id>
<icon>http://foakh.com/media/catalog/category/cache/11/thumbnail/100x/9df78eab33525d08d6e5fb8d27136e95/yyyy.jpg</icon>
</item>
</items>
</category>
I have to pull the data of tag and save it in the list and after that I have to show it in the custom listview. There is a method after_product(product_list) where the data are taken to the activity. Here is the code for parsing XML data but the data are not saved in the listview and as a result data are not displaying in the listview. It is obvious that I have done some mistake but can't figure it out. So can anybody help me out of this.
#Override
public void onSuccess(String response) {
// TODO Auto-generated method stub
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser mSaxParser = factory.newSAXParser();
XMLReader mXmlReader = mSaxParser.getXMLReader();
mXmlReader.setContentHandler(this);
BufferedReader br = new BufferedReader(new StringReader(response));
InputSource is = new InputSource(br);
mXmlReader.parse(is);
} catch (Exception e) {
Log.e("TAG", "Exception: " + e.getMessage());
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
tempval = new String(ch, start, length);
if (b_label == true)
str_label = str_label + tempval;
}
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if (localName.equalsIgnoreCase("items"))
product_list = new ArrayList<Products>();
if (localName.equalsIgnoreCase("item"))
productdto = new Products();
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if (localName.equalsIgnoreCase("label")) {
productdto.setLabel(tempval);
str_label = "";
b_label = false;
} else if (localName.equalsIgnoreCase("entity_id"))
productdto.setEntity_id(tempval);
else if (localName.equalsIgnoreCase("next"))
productdto.setNext(tempval);
else if (localName.equalsIgnoreCase("subcategory"))
productdto.setSubcategory(tempval);
else if (localName.equalsIgnoreCase("content_type"))
productdto.setContent_type(tempval);
else if (localName.equalsIgnoreCase("parent_id")) {
if (productdto != null)
productdto.setParent_id(tempval);
}
else if (localName.equalsIgnoreCase("icon"))
productdto.setIcon(tempval);
else if (localName.equalsIgnoreCase("items")) {
((ProductList) mActivity).after_product(product_list);
}
}
The method after_product(product_list) is given below:-
public void after_product(ArrayList<Products> product_list) {
productAdapter = new ProductListItemsAdapter(ProductList.this, 0, product_list);
list_view.setAdapter(productAdapter);
dialog.dismiss();
}
I have got stucked here. Please help me out.
There have some point that you should check out:
XML parse is work well?
If not, make sure XML parse work well.
Is productdto added to the product_list after parsed?
According to your code, I think you should add case in your "endElement" function like this:
else if (localName.equalsIgnoreCase("item"))
product_list.add(productdto);
Make sure "ProductListItemsAdapter" work well.
Hope my answer is helpful for you,sorry about my English is so bad :P

XML Parser returns last item, not the rest

my XML Content: (FileName: sku.xml)
<skus>
<id>p1</id>
<id>test</id>
<id>aa</id>
<id>bb</id>
<id>cc</id>
<id>dd</id>
<id>ee</id>
<id>ff</id>
<id>gg</id>
<id>hh</id>
<id>ii</id>
<id>jj</id>
<id>kk</id>
<id>ll</id>
</skus>
my SAX XML PARSER Class:
public class SAXXMLParser {
public static List<XMLSetAdd> parse(InputStream is) {
List<XMLSetAdd> setAdds = null;
try {
// create a XMLReader from SAXParser
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser()
.getXMLReader();
// create a SAXXMLHandler
SAXXMLHANDLER saxHandler = new SAXXMLHANDLER();
// store handler in XMLReader
xmlReader.setContentHandler(saxHandler);
// the process starts
xmlReader.parse(new InputSource(is));
// get the News list`
setAdds = saxHandler.getIds();
} catch (Exception ex) {
Log.d("XML", "SAXXMLParser: parse() failed");
ex.printStackTrace();
}
// return News list
return setAdds;
}
}
My SAX XML HANDLER:
public class SAXXMLHANDLER extends DefaultHandler {
private List<XMLSetAdd> setAdds;
private String tempVal;
// to maintain context
private XMLSetAdd setAdd;
public SAXXMLHANDLER() {
setAdds = new ArrayList<XMLSetAdd>();
}
public List<XMLSetAdd> getIds() {
return setAdds;
}
// Event Handlers
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equals("skus")) {
setAdd = new XMLSetAdd();
}
}
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.equals("skus")) {
setAdds.add(setAdd);
} else if (qName.equals("id")) {
setAdd.setId(tempVal);
}
}
}
my XML SetAdd:
public class XMLSetAdd {
public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
}
private String Id;
}
My Async Class:
private class GetXMLTask extends AsyncTask<String, Void, List<XMLSetAdd>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(List<XMLSetAdd> news) {
try
{
for (int i = 0; i < IdsL.size(); i++)
{
skusList.add(IdsL.get(i).getId());
Log.d("XML content",IdsL.get(i).getId());
}
skusQuery = new Bundle();
skusQuery.putStringArrayList("ITEM_ID_LIST", skusList);
GetAllSkusAsync runner = new GetAllSkusAsync();//Some Async to run after
runner.execute();
}
catch (Exception ex)
{
Log.d("Error Reading XML: ", ex.toString());
Toast.makeText(
getApplicationContext(),"Connection Error!"
Toast.LENGTH_SHORT).show();
}
}
/*
* uses HttpURLConnection to make Http request from Android to download
* the XML file
*/
private String getXmlFromUrl(String urlString) {
StringBuffer output = new StringBuffer("");
try {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
}
} catch (Exception ex) {
Log.d("Error in asyncTask XML: ", ex.toString());
ex.printStackTrace();
}
return output.toString();
}
private List<XMLSetAdd> IdsL;
#Override
protected List<XMLSetAdd> doInBackground(String... urls) {
IdsL = null;
List<XMLSetAdd> myList = null;
String xml = null;
for (String url : urls) {
xml = getXmlFromUrl(url);
InputStream stream = new ByteArrayInputStream(xml.getBytes());
IdsL = SAXXMLParser.parse(stream);
myList = SAXXMLParser.parse(stream);
}
// stream.close();
return IdsL;
}
}
The code which I use to call Async Class:
String URL = "http://someaddress/php/sku.xml";
GetXMLTask task = new GetXMLTask();
task.execute(new String[] { URL });
Now When I run this code and Log the result ,my list returns the last xml child which based on my xml file is "ll" and the rest of xml is not added to the file.
The list should return all of the ids but returns the last one.
Check following code. Edited SAX XML HANDLER.
public class SAXXMLHANDLER extends DefaultHandler {
private List<XMLSetAdd> setAdds;
private String tempVal;
// to maintain context
private XMLSetAdd setAdd;
public SAXXMLHANDLER() {
}
public List<XMLSetAdd> getIds() {
return setAdds;
}
// Event Handlers
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equals("skus")) {
setAdds = new List<XMLSetAdd>();
}else if(qName.equals("id")){
setAdd = new XMLSetAdd();
}
}
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.equals("skus")) {
} else if (qName.equals("id")) {
setAdd.setId(tempVal);
setAdds.add(setAdd);
}
}
}
The reason is because you are only adding items to the list when endElement is skus. You should be adding one element for each id as follows:
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("skus")) {
// setAdds.add(setAdd); // dont add here..
} else if (qName.equals("id")) {
setAdd.setId(tempVal); // if ending with id
setAdds.add(setAdd); // then add id to the list
}
}
Update
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equals("id")) {
setAdd = new XMLSetAdd(); // new item for each id
}
}
#Override
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
curentElement=localName;
if(qName.equals("skus")){
setAdd = new XMLSetAdd();
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
String value = new String(ch, start, length);
if(curentElement.equals("id")){
tempVal=value;
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
curentElement = "";
if (localName.equals("id")) {
setAdd.setId(tempVal);
}else if(localName="skus"){
setAdds.add(setAdd);
}
Try this way
Update your parse
public class SAXXMLHANDLER extends DefaultHandler {
private List<XMLSetAdd> setAdds;
private String tempVal;
// to maintain context
private XMLSetAdd setAdd;
public SAXXMLHANDLER() {
setAdds = new ArrayList<XMLSetAdd>();
}
public List<XMLSetAdd> getIds() {
return setAdds;
}
// Event Handlers
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// reset
if (qName.equals("id")) {
tempVal = "";
setAdd = new XMLSetAdd();
}
}
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.equals("id")) {
setAdd.setId(tempVal);
setAdds.add(setAdd);
}
}

Android SAXParse Get Value Between Tags

I have an XML file I am reading in via SAXParser, but I am having trouble reading it in correctly. The XML is structured like this:
<game>
<players>
<player>
<name>Player 1</name>
<score>100</score>
</player>
</players>
</game>
How can I get the Android SAXParser to read the values between tags? This is the code that I have, but it is looking for an attribute to the tag, not the text between.
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(localName.equals("name")) {
names.add(attributes.getValue("name"));
}
else if(localName.equals("score")) {
scores.add(Integer.parseInt(attributes.getValue("score")));
}
}
Drawing from the example #
http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/
More info about sax #
http://docs.oracle.com/javase/tutorial/jaxp/sax/parsing.html
Apart from sax you should have a look at xmllpullparser which is recommended.
Quoting from the docs.
We recommend XmlPullParser, which is an efficient and maintainable way to parse XML on Android.
Check the link #
http://developer.android.com/training/basics/network-ops/xml.html
public void readxml(){
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean bname = false;
boolean bscore = false;
public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("name")) {
bname = true;
}
if (qName.equalsIgnoreCase("score")) {
bscore = true;
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
}
public void characters(char ch[], int start, int length) throws SAXException {
if (bname) {
Toast.makeText(getApplicationContext(), new String(ch, start, length), 10000).show();
bname = false;
}
if (bscore) {
Toast.makeText(getApplicationContext(), new String(ch, start, length), 10000).show();
bscore = false;
}
}
};
saxParser.parse("myxmltoparse", handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}

SAX RSS FEED parser

I am trying to parse a RSS feed using SAX parser
This is my code:
public class MainActivity extends Activity {
ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();
ListView list;
ArrayList<String> sinlgeItem = null;
ProgressDialog pd;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list=(ListView)findViewById(R.id.list);
boolean b=parseData();
Log.v("result", "value"+b);
for(int i=0;i<data.size();i++){
Log.e("ITEM",data.get(i).get(0)+"__"+data.get(i).get(1));
}
}
/**
* method parse the data
*/
private boolean parseData() {
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
URL url = new URL("https://itunes.apple.com/WebObjects/MZStore.woa/wpa/MRSS/newreleases/sf=143441/limit=25/rss.xml");
xr.setContentHandler(new MyHandler());
xr.parse(new InputSource(url.openStream()));
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public class MyHandler extends DefaultHandler{
Boolean ITEM=false;
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
}
#Override
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
if (ITEM){
RootElement root=new RootElement("rss");
Element chan=root.getChild("channel");
Element itms=chan.getChild("item");
Element title=itms.getChild("title");
Element artist=itms.getChild("http://phobos.apple.com/rss/1.0/modules/itms/", "artist");
title.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
sinlgeItem.add(body);
Log.v("title",body);
}
});
artist.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
sinlgeItem.add(body);
Log.v("artist", body);
}
});
ITEM=false;
data.add(sinlgeItem);
}
}
#Override
public void startDocument() throws SAXException {
super.startDocument();
}
#Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
if (localName.equals("item")){
sinlgeItem = new ArrayList<String>();
ITEM=true;
}
}
}
}
This is the link to the xml feed
https://itunes.apple.com/WebObjects/MZStore.woa/wpa/MRSS/newreleases/sf=143441/limit=25/rss.xml
I am trying to parse the title element with in the item tag and the element itms:artist with in the item tag.
I don't know how to handle tags with name spaces
Refer the following example's
Example on RSSFeed parsing
Simple RSSReader example
Complete guide on Reading RSS Feeds
Display news&videos through RSSFeeds
I don't think you should use SAXParser for parsing RSS. It would be easier using XML Pull Parser. I would choose to SAXParser for parsing a continuous client-server communication like XMPP Protocol since SAX is best for for parsing incomplete and continuous XML.

Android: Sax Reader, can't extract information needed

I am receiving a response from a XML request and I need to deal with it. The response will return either '00' when the request has been accepted and the account is verified and a '03' when the account is invalid.
Currently the Sax Reader is returning the correct information but I cannot extract the information from the reader so I can store the username / password into the internal storage of the phone.
The code from the Sax Reader is:
public void inputStreamToString(InputStream is) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean errorCode = false;
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("ErrorCode"))
{
errorCode = true;
}
}
public void endElement(String uri, String localName,String qName) throws SAXException
{
System.out.println("End Element :" + qName);
}
public void characters(char ch[], int start, int length) throws SAXException
{
if (errorCode)
{
System.out.println("ErrorCode : "+ new String(ch, start, length));
if (ch.equals(00))
{
System.out.println("IT WORKS!!!");
}
errorCode = false;
}
}
};
saxParser.parse(is, handler);
}
catch (Exception e)
{
System.out.println("Sax Error");
e.printStackTrace();
}
}
As you can see in the public void characters it is printing out the errorcode that is relevant from the response. I am currently trying to do ch.equals(00) in a If statement but it isn't picking out the correct information! Could it be a problem that ch is a char data type?
Any help will be appreciated.
I got it working. Instead of using '00' and '03' error codes. I have used the length of the response messages which are 'OK' and 'Invalid'.

Categories

Resources