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.
Related
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();
}
}
}
i'm trying to parse rss feed in my android app.
and my feed contains a lot of items with tags "tag"
it looks like
<item>
<title> title </title>
<link> link </link>
<pubDate> date </pubDate>
<description> description </description>
<tags>
<tag id="1">first</tag>
<tag id="2">second</tag>
<tag id="3">third</tag>
</tags>
</item>
my question:
how can i select items only with specific "tag" eg. tag="second'?
rewrote a Xml Factory class I had, it should lead you on the right track.
/**
*
* #author hsigmond
*
*/
public class RssXmlFactory {
public static ArrayList<RSSItem> parseResult(final String rssDataContent,String tag_id) throws ParserConfigurationException,
SAXException, IOException {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
public String mItemTagID=tag_id;//"2"
RSSItemsHandler parser = new RSSItemsHandler();
xr.setContentHandler(parser);
StringReader sr = new StringReader(rssDataContent);
InputSource is = new InputSource(sr);
xr.parse(is);
return parser.mItemList;
}
}
class RSSItemsHandler extends DefaultHandler {
private StringBuilder mSb = new StringBuilder();
public ArrayList<RSSItem> mItemList = new ArrayList<RSSItem>();
public RSSItem mCurrentRssItem = null;
public String mItemTitle="";
#Override
public void startElement(final String namespaceURI, final String localName, final String qName,
final Attributes atts) throws SAXException {
mSb.setLength(0);
if (localName.equals(XMLTag.TAG_RSS_ITEM_ROOT)) {
/** Get the rss item title attribute value */
mItemTitle=atts.getValue(XMLTag.TAG_RSS_ITEM_TITLE);
//#TODO Log result
}
else if (localName.equals(XMLTag.TAG_RSS_ITEM_TAG_ROOT)) {
//This is where you check if the TAG equals id=2, did not have the time to check if it works yet, it's late...
if(atts.getValue(XMLTag.TAG_RSS_ITEM_TAG_ID).equalsIgnoreCase(mItemTagID)){//id="2"
mCurrentRssItem = new RSSItem();
/** Set item title attribute value */
mCurrentRssItem.title=mItemTitle;
//#TODO Log result
}
}
}
#Override
public void endElement(final String namespaceURI, final String localName, final String qName) throws SAXException {
if (localName.equals(XMLTag.TAG_RSS_ITEM_ROOT)) {
mItemList.add(mCurrentRssItem);
} else if (localName.equals(XMLTag.TAG_RSS_ITEM_TAG_ROOT)) {
mCurrentRssItem.tag = mSb.toString();
}
}
#Override
public void characters(final char[] ch, final int start, final int length) throws SAXException {
super.characters(ch, start, length);
mSb.append(ch, start, length);
}
}
}
For more details on how to handle XML on Android look here: http://www.ibm.com/developerworks/opensource/library/x-android/index.html
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.
I have a problem when parsing xml from the internet. The parser doesn't return all the data correctly.
Three are three errors:
correct result -->return result
161:1:161-->1:1:161
330:2:132-->3:2:132
421:2:223-->4:2:223
Copy of the xml file I am trying to parse
https://docs.google.com/open?id=0BwXEx9yI14inT1BnR2xzYnJEX0E
Activity
public class DataBaseUpdateService_1 extends Activity {
private TextView TextView1 ;
private LinearLayout linearlayout1 ;
private TextView title[];
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_item);
linearlayout1 = (LinearLayout)findViewById(R.id.linearlayout1);
TextView1 = (TextView)findViewById(R.id.textView1);
MyDBHelper dbHelper =new MyDBHelper(DataBaseUpdateService_1.this);
SQLiteDatabase db = dbHelper.getWritableDatabase();
try {
/** Handling XML */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Send URL to parse XML Tags */
URL sourceUrl = new URL(
"http://123.com/example.xml");
/** Create handler to handle XML Tags ( extends DefaultHandler ) */
DataBaseUpdate_XMLHandler XMLHandler = new DataBaseUpdate_XMLHandler();
xr.setContentHandler(XMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
}catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
int itemCount = DataBaseUpdate_XMLHandler.array.size();
db.delete("hymns_match", null, null);
try{
for(int i=0;i<itemCount;i++) {
String songs_id=DataBaseUpdate_XMLHandler.array.get(i).get("songs_id");
String songs_book_id=DataBaseUpdate_XMLHandler.array.get(i).get("songs_book_id");
String songs_book_ch=DataBaseUpdate_XMLHandler.array.get(i).get("songs_book_ch");
TextView tv = new TextView(DataBaseUpdateService_1.this);
tv.setText(songs_id + ":"+songs_book_id+ ":"+songs_book_ch);
linearlayout1.addView(tv);
}
}catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
}
}
DataBaseUpdate_XMLHandler
public class DataBaseUpdate_XMLHandler extends DefaultHandler {
Boolean currentElement = false;
String currentValue=null;
static ArrayList<LinkedHashMap<String, String>> array;
LinkedHashMap map;
#Override
public void startDocument() throws SAXException {
array = new ArrayList<LinkedHashMap<String, String>>();
}
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentElement = true;
if (localName.equals("song")) {
map = new LinkedHashMap<String, Object>();
currentValue=null;
}
/*Get attribute
* else if (localName.equals("website")) {
* String attr = attributes.getValue("category");
* sitesList.setCategory(attr);}
* */
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
currentElement = false;
/** set value */
if (localName.equalsIgnoreCase("songs_id")){
map.put("songs_id",currentValue);}
else if (localName.equalsIgnoreCase("songs_book_id")){
map.put("songs_book_id", currentValue);}
else if (localName.equalsIgnoreCase("songs_book_ch")){
map.put("songs_book_ch", currentValue);}
else if (localName.equalsIgnoreCase("song")){
array.add(map);}
}
/** Called to get tag characters
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (currentElement) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}
}
Can you give some advice about what's wrong here?
According to the SAX definition characters() method can be called multiple times per elements. So it should accumulate the text; if this is happening then your code will not work.
I have a XML file in assets folder.
I am parsing it in my Activity and displaying it.
In XML file I has a data with < symbol, I use < at < symbol.
But, the symbol is not displying and text after the symbol only i am getting.
ex "hi < hello"
parsing result will be only hello
parsing code
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SecondHandler shandler = new SecondHandler();
xr.setContentHandler(shandler);
InputStream in = this.getAssets().open(fileName);
xr.parse(new InputSource(in));
itemlist = shandler.getParsedData();
} catch (Exception e) {
System.out.println("Error : " + e);
}
Map<String, String> item = (Map<String, String>) list.get(5);
String qus = item.get("question");
String ans = item.get("answer");
}
xml file..
..........
<dict>
<question>hello</question>
<answer>I am < 5 you</answer>
</dict>
......
handler code.
public class SecondHandler extends DefaultHandler {
private String tagName;
#SuppressWarnings("rawtypes")
private ArrayList<Map> dataSet;
private Map<String, String> dictionary;
#SuppressWarnings("rawtypes")
public ArrayList<Map> getParsedData() {
return dataSet;
}
#Override
public void startDocument() throws SAXException {
}
#Override
public void endDocument() throws SAXException {
// Nothing to do
}
#SuppressWarnings("rawtypes")
#Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
tagName = localName;
if (localName.equals("array")) {
this.dataSet = new ArrayList<Map>();
} else if (localName.equals("dict")) {
dictionary = new HashMap<String, String>();
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("array")) {
} else if (localName.equals("dict")) {
dataSet.add(dictionary);
}
}
#Override
public void characters(char ch[], int start, int length) {
String string = new String(ch, start, length);
string = string.replaceAll(" ", "");
string = string.replaceAll("\n", "");
string = string.replaceAll("\t", "");
if (string.length() > 0 && string != null) {
dictionary.put(tagName, new String(ch, start, length));
// System.out.println("Dictionary : " + dictionary);
}
}
}
How to solve this problem
Thanks in advance...!
A SAX parser can supply character data to the ContentHandler in as many calls of the characters() method as it chooses. Your characters() method is putting each of the substrings in the same hashtable entry, overwriting any previous substrings; you need to concatenate them.
may be you directly use "<" in xml file write ,
So use Value-->String class
==>string name="temperature_lt" value is= Temperature & l t;(Note here ignore space)
and extractin xml file
==>android:text="#string/temperature_lt"
try it,