reiley
reiley

Reputation: 3761

SAX parsing: how to fetch child nodes

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

Answers (4)

user1869209
user1869209

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

androiddeveloper2011
androiddeveloper2011

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

parsifal
parsifal

Reputation: 1663

SAX is the wrong tool for this job. Your requirements would be easily solved using DOM and XPath.

Upvotes: 1

meredrica
meredrica

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

Related Questions