0

I have an xml file as

<?xml version="1.0" encoding="utf-8"?>
<sections>
    <section>
        <name>Most Pouplar</name>
        <items>
            <item pos="1">
                <name>
                    AcaiBerry Diet
                </name>
                <description>

                    <![CDATA[
                    Natrol AcaiBerry Diet supports weight loss goals when combined with a healthy reduced-calorie diet and exercise program. Acai is a wild fruit harvested in the rain forests of Brazil recognized for its high ORAC (oxygen-radical absorbance capacity) value - a measure of its antioxidant capacity. An adequate intake of antioxidants helps neutralize harmful free radicals that are produced by the body as a result of regular exercise.
                    ]]>
                </description>
            </item>
            <item pos="2">
                <name>
                    AcaiBerry Weekend Cleanse
                </name>
                <description>
                    <![CDATA[
                    AcaiBerry Weekend Cleanse is a 3-step, easy-to-use cleansing program. Step 1 helps minimize occasional constipation/bloating, step 2 helps reduce toxins via antioxidant protection & cell regeneration and step 3 helps to restore the friendly bacteria that protect & strengthen the GI tract.
                    ]]>

                </description>
            </item>
            <item pos="4">
                <name>
                    Carb Intercept Phase 2 + Chromium
                </name>
                <description>
                    <![CDATA[
                    Natrol Carb Intercept supports a low-carb lifestyle by controlling carbohydrates found in breads, cereals, rice, pasta and other starch-containing foods. Each serving provides 1,000mg of Phase 2 Carb Controller; a clinically tested ingredient that inhibits the enzyme responsible for digesting starch into simple sugars your body can absorb.
                    ]]>
                </description>

            </item>
            <item pos="3">
                <name>
                    Resveratrol Diet
                </name>
                <description>
                    <![CDATA[
                    Losing weight has never been so rejuvenating! Natrol introduces Resveratrol Diet, a complex blend of antioxidants, enzymes and other nutrientsto help boost your metabolism and promote calorie burning.
                    ]]>
                </description>
            </item>

        </items>
    </section>    
    <section>
        <name>Least Popular</name>
        <items>
            <item pos="1">
                <name>
                    Advanced Sleep Melatonin 10mg Maximum Strength
                </name>

                <description>
                    <![CDATA[
                    Getting a good night's sleep is even easier with Natrol Melatonin - a natural nightcap. A hormone found in the body, melatonin, helps promote more restful sleep. Natrol Melatonin provides relief for occasional sleeplessness, and helps promote a more relaxing night and better overall health.
                    ]]>
                </description>
            </item>
            <item pos="2">
                <name>
                    Sleep 'N Restore
                </name>
                <description>

                    <![CDATA[
                    If you need to feel more rested due to lack of sleep, try Natrol Sleep 'N Restore. Sleep 'N Restore helps promote a more restful, deeper sleep, while supporting your body's natural restoration processes.* A combination of melatonin and valerian, this natural sleep aide includes antioxidants that can help your body protect its cells from damage to help you restore and recharge while you sleep.
                    ]]>
                </description>
            </item>
        </items>
    </section>    
</sections>

I defined a POJO as

public class ItemPojo {

    //Fields of an item
    private String itemName;
    private String itemDescription;
    private int itemPosition;

    //Getters and Setters 
    public String getItemName() {
        return itemName;
    }
    public void setItemName(String itemName) {
        this.itemName = itemName;
    }
    public String getItemDescription() {
        return itemDescription;
    }
    public void setItemDescription(String itemDescription) {
        this.itemDescription = itemDescription;
    }
    public int getItemPosition() {
        return itemPosition;
    }
    public void setItemPosition(int itemPosition) {
        this.itemPosition = itemPosition;
    }
}

I am implementing a method for parsing xml file, but I have no idea about how can I read multiple <item> tag, which are within <items> tag.

Edited

I am putting part of code, which I am trying

//Store all items with a particular section 
ArrayList<ItemPojo> itemList = new ArrayList<ItemPojo>();
//Store all items categorized by section 
Map<String, ArrayList<ItemPojo>> itemStore = new HashMap<String, ArrayList<ItemPojo>>(1);
//Single item
ItemPojo currentItem = null;
//Current section name
String sectionName = null;

public AndroidSaxFeedParser() {
    super();
}

public void parse() { //Map<String, ArrayList<ItemPojo>>

    RootElement root = new RootElement(SECTIONS);

    Element section = root.getChild(SECTION);
    Element itemHeader = section.getChild(ITEM_HEADER);



    //Read <name> tag as used as section
    itemHeader.setEndTextElementListener(new EndTextElementListener() {         
        public void end(String body) {
            sectionName = body;
        }
    });
    //TODO set item header here

    Element items = section.getChild(ITEMS);
    Element item = items.getChild(ITEM);

    /*//Put all items of same category
    items.setEndTextElementListener(new EndTextElementListener() {

        public void end(String body) {

            //sort item with position 
            Collections.sort(itemList, ItemPojo.COMPARE_BY_POSITION);
            //Putting it into master list
            itemStore.put(sectionName, itemList);
            //And clear the item list
            itemList.clear();
        }
    });*/

    item.setStartElementListener(new StartElementListener() {           
        public void start(Attributes attributes) {
            currentItem = new ItemPojo();
            Log.i("Test xml", "item initalised " + currentItem.toString());
        }
    });

    item.setEndTextElementListener(new EndTextElementListener() {

        public void end(String body) {
            // TODO Auto-generated method stub
            itemList.add(currentItem);
            Log.i("Test xml", "New items found " + currentItem.toString());
        }
    });

    item.getChild(ITEM_NAME).setEndTextElementListener(new EndTextElementListener() {           
        public void end(String body) {
            currentItem.setItemName(body);
        }
    });

    item.getChild(DESCRIPTION).setEndTextElementListener(new EndTextElementListener() {

        public void end(String body) {
            currentItem.setItemDescription(body);
        }
    });

    try {
        Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    //return itemStore;
}

Now I am getting exception as

06-30 12:40:45.312: ERROR/AndroidRuntime(315): Uncaught handler: thread main exiting due to uncaught exception
06-30 12:40:45.342: ERROR/AndroidRuntime(315): java.lang.IllegalStateException: This element already has an end text element listener. It cannot have children.
06-30 12:40:45.342: ERROR/AndroidRuntime(315):     at android.sax.Element.getChild(Element.java:68)
06-30 12:40:45.342: ERROR/AndroidRuntime(315):     at android.sax.Element.getChild(Element.java:60)
06-30 12:40:45.342: ERROR/AndroidRuntime(315):     at org.us.ssg.AndroidSaxFeedParser.parse(AndroidSaxFeedParser.java:82)
06-30 12:40:45.342: ERROR/AndroidRuntime(315):     at org.us.ssg.DesTestDemoActivity.checkXml(DesTestDemoActivity.java:109)
06-30 12:40:45.342: ERROR/AndroidRuntime(315):     at org.us.ssg.DesTestDemoActivity.onClick(DesTestDemoActivity.java:81)
06-30 12:40:45.342: ERROR/AndroidRuntime(315):     at android.view.View.performClick(View.java:2364)
06-30 12:40:45.342: ERROR/AndroidRuntime(315):     at android.view.View.onTouchEvent(View.java:4179)
06-30 12:40:45.342: ERROR/AndroidRuntime(315):     at android.widget.TextView.onTouchEvent(TextView.java:6541)

What I need

I need to read all items (with pos, name and description) and section. I am taking a HashMap, as key I am putting section and as value of that key I am puting an ArrayList of all items (with pos, name, description) related to that particular key (as section name).

2 Answers 2

2

You are well on your way. Next step is:

  1. Define a startElementListener for you item element. Like this:

    item.setStartElementListener(new StartElementListener() {          
                @Override
                public void start(Attributes attributes) {
                    myPojoItem = new PojoItem();
                }
            });
  2. Define a endElementListener for you item element: Like this:

    item.setEndElementListener(new EndElementListener() {
                @Override
                public void end() {
                    itemList.add(myPojoItem);
                }
            });
  3. For each of the children of item do something like the following:

    itemName.setEndTextElementListener(new EndTextElementListener() {
                @Override
                public void end(String body) {
                                   myPojoItem.setName(body);
                }
            });
  4. finish with:

    try {
                Xml.parse(myXmlAsFileInputStream, Xml.Encoding.UTF_8, root.getContentHandler());
            } catch (Exception e) {
                e.printStackTrace();
            }

Update: In response to comment by OP, here is how to access attributes of elements:

item.setStartElementListener(new StartElementListener() {
    @Override
    public void start(Attributes attributes) {
        position = attributes.getValue("pos");
    }
});

Final solution

From OP : I have done it with these way

AndroidSaxFeedParser.java

.

public class AndroidSaxFeedParser extends BaseFeedParser {

    //Store all items with a particular section 
    ArrayList<ItemPojo> itemList = new ArrayList<ItemPojo>();
    //Store all items categorized by section 
    Map<String, ArrayList<ItemPojo>> itemStore = new HashMap<String, ArrayList<ItemPojo>>(1);
    //Single item
    ItemPojo currentItem = null;
    //Current section name
    String sectionName = null;

    public AndroidSaxFeedParser() {
        super();
    }

    public Map<String, ArrayList<ItemPojo>> parse() { 

        RootElement root = new RootElement(SECTIONS);

        Element section = root.getChild(SECTION);
        Element itemHeader = section.getChild(ITEM_HEADER);

        //Read <name> tag as used as section
        itemHeader.setEndTextElementListener(new EndTextElementListener() {         
            public void end(String body) {
                sectionName = body.trim();
                Log.i("New Section", "New section found : " + sectionName);
            }
        });


        section.setStartElementListener(new StartElementListener() {            
            public void start(Attributes attributes) {
                //Clear the item list
                itemList = new ArrayList<ItemPojo>(0);
                Log.i("Size of list", "Size : " +itemList.size());
            }
        });
        section.setEndElementListener(new EndElementListener() {            
            public void end() {
                //Putting it into master list
                itemStore.put(sectionName, itemList);
            }
        });

        Element items = section.getChild(ITEMS);
        Element item = items.getChild(ITEM);

        items.setEndElementListener(new EndElementListener() {

            public void end() {
                //sort item with position 
                Collections.sort(itemList, ItemPojo.COMPARE_BY_POSITION);               
            }
        });     

        item.setStartElementListener(new StartElementListener() {

            public void start(Attributes attributes) {
                currentItem = new ItemPojo();
                currentItem.setItemPosition(Integer.parseInt(attributes.getValue("pos")));
                //Log.i("Test xml", "item initalised " + currentItem.toString());           
            }
        });

        item.setEndElementListener(new EndElementListener() {

            public void end() {

                itemList.add(currentItem);
                Log.i("Test xml", "New items found " + currentItem.toString());
            }
        });

        item.getChild(ITEM_NAME).setEndTextElementListener(new EndTextElementListener() {           
            public void end(String body) {
                currentItem.setItemName(body.trim());
            }
        });

        item.getChild(DESCRIPTION).setEndTextElementListener(new EndTextElementListener() {

            public void end(String body) {
                currentItem.setItemDescription(body.trim());
            }
        });

        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return itemStore;
    }
}

.

public abstract class BaseFeedParser implements FeedParser {

    // names of the XML tags
    static final String SECTIONS = "sections";
    static final String SECTION = "section";
    static final String ITEM_HEADER = "name";
    static final  String DESCRIPTION = "description";
    static final  String ITEM_NAME = "name";
    static final  String ITEM_POSITION = "pos";
    static final  String ITEM = "item";
    static final  String ITEMS = "items";
    public InputStream inStream;

    public BaseFeedParser() {
        //super();
    }

    protected InputStream getInputStream() {
        //Create a new HttpClient and Post Header
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(DesTestDemoActivity.INDEX_URL);
        HttpResponse response = null;
        try {
            // Add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("request_for", "xml_data"));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            // Execute HTTP Post Request
            response = httpclient.execute(httppost);    
            HttpEntity entity = response.getEntity();
            if (entity != null)
                inStream = entity.getContent(); 
            return inStream;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

.

public interface FeedParser {
    Map<String, ArrayList<ItemPojo>> parse();
}

I have done with the help of you guys. So thank you all.

Sign up to request clarification or add additional context in comments.

7 Comments

I could use a hand with the formatting of this answer, is there a guide somewhere I could read?
Read this: ibm.com/developerworks/opensource/library/x-android/#N101E0 The example in Listing 8 is exactly what you need
@user594955: Basically, every time the parser reaches a new item, you create a new item, and when the parser reaches the end of an item, you add that item to the item list. In between, the parser will reach all the child elements of the item, and all you have to do is extract the data from these elements and store them in the PojoItem object, using the endElementListener
@videre I am using this method, but how can I read value within tags like <item pos="4">, I want to read pos value.
@user594955: I've now updated the answer to include extraction of attribute values.
|
1

You don't seem to be using a SAX parser here but doing a DOM traveral.

If you want to parse the XML with a SAX parser, you need to initialize a SAXParser and define a ContentHandler where you will implement your parsing logic.

SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();

/** Send URL to parse XML Tags */
URL sourceUrl = new URL(xmlFile);

/** Create handler to handle XML Tags ( extends DefaultHandler ) */
MyXMLHandler myXMLHandler = new MyXMLHandler();
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));

The ContentHandler has callbacks for when the parser reaches a start and end element. There you can put the logic required to fill up your POJO.

In your particular case, you need to check for the item tag and start filling up your POJOs.

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MyXMLHandler extends DefaultHandler {

@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {

if (localName.equals("sometag")) {
// process tag
}

}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// handle end element
}
}

There are several articles on the web with full code samples for this. Just google for Android and SAX Parser.

One example where an XML file (containing item elements) is parsed using SAX can be found here.

2 Comments

Can you sare some links about it, please? And is this specific for Android
See updated answer for an android sample using SAX. The sample is an Android app, but the SAX parsing itself doesn't contain any Android specifics.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.