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
?
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 ;)
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());
}
}
}
SAX is the wrong tool for this job. Your requirements would be easily solved using DOM and XPath.
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;
}
来源:https://stackoverflow.com/questions/14236767/sax-parsing-how-to-fetch-child-nodes