Reputation: 3761
I'm using SAX parsing in android. For below XML:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Game Analysis</title>
<item>
<title>GTA</title>
<description>ABC</description>
<pubDate>Sat, 21 Feb 2012 05:18:23 GMT</pubDate>
<enclosure type="audio/mpeg" url="http://URL.mp3" length="6670315"/>
</item>
<item>
<title>CoD</title>
<description>XYZ</description>
<pubDate>Sat, 21 Feb 2011 05:18:23 GMT</pubDate>
<enclosure type="audio/mpeg" url="http://URL.mp3" length="6670315"/>
</item>
</channel>
</rss>
I need to fetch the first occurance of <title>
(just below ).
Then from every block I again need to extract <title> & <enclosure>
.
I can fetch the first <title>
using:
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equals("title"))
...
}
But, how should I fetch the tags inside <item> block
?
Upvotes: 7
Views: 15789
Reputation:
Here is how I've done that with SAX.
I have modified a bite your XML file.
XML file
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Game Analysis</title>
<item>
<title>GTA</title>
<description>ABC</description>
<pubDate>Sat, 21 Feb 2012 05:18:23 GMT</pubDate>
<enclosure type="audio/mpeg" url="http://URL.mp3/1" length="6670315"/>
</item>
<item>
<title>CoD</title>
<description>XYZ</description>
<pubDate>Sat, 21 Feb 2011 05:45:10 GMT</pubDate>
<enclosure type="audio/mpeg" url="http://URL.mp3/2" length="6670345"/>
</item>
<item>
<title>AtV</title>
<description>fgh</description>
<pubDate>Sat, 21 Feb 2011 06:20:10 GMT</pubDate>
<enclosure type="audio/mpeg" url="http://URL.mp3/3" length="6670364"/>
</item>
</channel>
<channel>
<title>Game Analysis 2</title>
<item>
<title>GTA 2</title>
<description>ABC 2</description>
<pubDate>Sat, 21 Feb 2012 04:18:23 GMT</pubDate>
<enclosure type="audio/mpeg" url="http://URL.mp3/2/1" length="6670315"/>
</item>
<item>
<title>CoD 2</title>
<description>XYZ 2</description>
<pubDate>Sat, 21 Feb 2011 04:45:10 GMT</pubDate>
<enclosure type="audio/mpeg" url="http://URL.mp3/2/2" length="6670345"/>
</item>
<item>
<title>AtV 2</title>
<description>fgh</description>
<pubDate>Sat, 21 Feb 2011 05:20:10 GMT</pubDate>
<enclosure type="audio/mpeg" url="http://URL.mp3/2/3" length="6670364"/>
</item>
</channel>
</rss>
Entities
Channel
public class Channel {
private String title;
private ArrayList<Item> alItems;
public Channel(){}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public ArrayList<Item> getAlItems() {
return alItems;
}
public void setAlItems(ArrayList<Item> alItems) {
this.alItems = alItems;
}
}
Enclosure
public class Enclosure {
private String type;
private URL url;
private Integer length;
public Enclosure(){}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public URL getUrl() {
return url;
}
public void setUrl(URL url) {
this.url = url;
}
public Integer getLength() {
return length;
}
public void setLength(Integer length) {
this.length = length;
}
}
Item
public class Item {
private String title;
private String description;
private String pubDate;
private Enclosure enclosure;
public Item(){}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPubDate() {
return pubDate;
}
public void setPubDate(String pubDate) {
this.pubDate = pubDate;
}
public Enclosure getEnclosure() {
return enclosure;
}
public void setEnclosure(Enclosure enclosure) {
this.enclosure = enclosure;
}
}
Handler
ChannelHandler
public class ChannelHandler extends DefaultHandler{
private ArrayList<Channel> alChannels;
private Channel channel;
private String reading;
private ArrayList<Item> alItems;
private Item item;
private Enclosure enclosure;
public ChannelHandler(){
super();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(qName.equals("rss")){
alChannels = new ArrayList<>();
}
else if(qName.equals("channel")){
channel = new Channel();
}
else if(qName.equals("item")){
item = new Item();
}
else if(qName.equals("enclosure")){
enclosure = new Enclosure();
enclosure.setType(attributes.getValue("type"));
try {
enclosure.setUrl(new URL(attributes.getValue("url")));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
enclosure.setLength(Integer.parseInt(attributes.getValue("length")));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(qName.equals("channel")){
channel.setAlItems(alItems);
alChannels.add(channel);
alItems = null;
}
if(qName.equals("title")){
if(alItems == null){
channel.setTitle(reading);
alItems = new ArrayList<>();
}
else if(item != null) {
item.setTitle(reading);
}
}
else if(qName.equals("item")){
if(alItems != null){
alItems.add(item);
item = null;
}
}
else if(qName.equals("description")){
item.setDescription(reading);
}
else if(qName.equals("pubDate")){
item.setPubDate(reading);
}
else if(qName.equals("enclosure")){
item.setEnclosure(enclosure);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
reading = new String(ch, start, length);
}
public ArrayList<Channel> getAlChannels() {
return alChannels;
}
}
Manager
XMLManager
public final class XMLManager {
public static ArrayList<Channel> getAlChannels(){
ArrayList<Channel> alChannels = null;
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser parser = factory.newSAXParser();
File file = new File("D:\\Loic_Workspace\\TestSAX2\\res\\test.xml");
ChannelHandler channelHandler = new ChannelHandler();
parser.parse(file, channelHandler);
alChannels = channelHandler.getAlChannels();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return alChannels;
}
}
The main
MyMain
public class MyMain {
/**
* @param args
*/
public static void main(String[] args) {
Enclosure enclosure = null;
for(Channel channel : XMLManager.getAlChannels()){
System.out.println("Channel title : "+channel.getTitle());
System.out.println("------------------------");
for(Item i:channel.getAlItems()){
System.out.println(i.getTitle());
System.out.println(i.getPubDate());
System.out.println("Enclosure : ");
enclosure = i.getEnclosure();
System.out.println(enclosure.getType());
System.out.println(enclosure.getUrl());
System.out.println(enclosure.getLength());
System.out.println("------------------------");
}
}
}
}
Output in the console
Channel title : Game Analysis
------------------------
GTA
Sat, 21 Feb 2012 05:18:23 GMT
Enclosure :
audio/mpeg
http://URL.mp3/1
6670315
------------------------
CoD
Sat, 21 Feb 2011 05:45:10 GMT
Enclosure :
audio/mpeg
http://URL.mp3/2
6670345
------------------------
AtV
Sat, 21 Feb 2011 06:20:10 GMT
Enclosure :
audio/mpeg
http://URL.mp3/3
6670364
------------------------
Channel title : Game Analysis 2
------------------------
GTA 2
Sat, 21 Feb 2012 04:18:23 GMT
Enclosure :
audio/mpeg
http://URL.mp3/2/1
6670315
------------------------
CoD 2
Sat, 21 Feb 2011 04:45:10 GMT
Enclosure :
audio/mpeg
http://URL.mp3/2/2
6670345
------------------------
AtV 2
Sat, 21 Feb 2011 05:20:10 GMT
Enclosure :
audio/mpeg
http://URL.mp3/2/3
6670364
------------------------
So it works ;)
Upvotes: 14
Reputation: 226
In place SAX parser use Dom parser and Below is your complete answer:-
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
.newInstance();
documentBuilderFactory.setCoalescing(true);
DocumentBuilder documentBuilder = documentBuilderFactory
.newDocumentBuilder();
Document document = documentBuilder.parse(new InputSource(is));
title = document.getElementsByTagName("title").item(0).getFirstChild().getNodeValue().trim();
itemList = document.getElementsByTagName("item");
for (int i = 0; i < itemList .getLength(); i++) {
if(itemModel == null){
itemModel = new ItemModel();
}
if(arrListItemModel==null){
arrListItemModel= new ArrayList<ItemModel>();
}
itemItem = (Element)itemList .item(i);
itemModel.setTitle(itemItem .getElementsByTagName("title").item(0).getFirstChild().getNodeValue().trim());
itemModel.setDescription(itemItem .getElementsByTagName("description").item(0).getFirstChild().getNodeValue().trim());
itemModel.setPubDate(itemItem .getElementsByTagName("pubDate").item(0).getFirstChild().getNodeValue().trim());
itemModel.setEnclosure(itemItem .getElementsByTagName("enclosure ").item(0).getFirstChild().getNodeValue().trim());
arrListItemModel.add(tippsModel);
itemModel =null;
}
Upvotes: 0
Reputation: 1663
SAX is the wrong tool for this job. Your requirements would be easily solved using DOM and XPath.
Upvotes: 1
Reputation: 2563
You use a stack (or similar) and remember whatever you need. SAX is event based and therefore you have to manage information about where you are on your own. Consider something like this:
public Parser extends ....
private Item item;
private StringBuffer buffer;
startElement(String uri,)...{
buffer = new StringBuffer();
}
characters(...) {
buffer.append(...); // sorry, coding by memory directly on SO, can't remember correct syntax.
}
endElement(String uri, String qName...) {
if(qName.equals("item") {
handleOldItem();
item = new Item();
} else if(qname.equals("title") {
item.setTitle(buffer.toString());
}
}
}
Upvotes: 0