Skip to content Skip to sidebar Skip to footer

Trouble With Xml Parsing Through JAVA

I am trying to parse xml through JAVA but after parsing I get org.apache.harmony.xml.dom.DocumentImpl@418b4c98. Here is the XML what I am tring to parse, for example, i need id dat

Solution 1:

Using XmlPullParser following the docs http://developer.android.com/training/basics/network-ops/xml.html

Copied xml to assests folder to parser locally ( for testing only ). You can get the xml from the url and parse.

 InputStream is = MainActivity.this.getResources()
                     .getAssets().open("xmlparser.xml");
               new parserPull(is);

Then to parse

public class parserPull
{

    private static final String ns = null;
    public parserPull(InputStream open) {
        try
        {
             XmlPullParser parser = Xml.newPullParser();
             parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
             parser.setInput(open, null);
             parser.nextTag();
             List<Entry> all = readFeed(parser);
             for(int i=0;i<all.size();i++)
             {
             Log.i("ID is..........",all.get(i).id);
             Log.i("Link is........",all.get(i).link);
             Log.i("Price is.......",all.get(i).price);
             }
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
         List<Entry> entry = null;
        parser.require(XmlPullParser.START_TAG, ns, "prestashop");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();
            //Log.i("..................",name);
            // Starts by looking for the prestashop tag
            if (name.equals("products")) {
              entry= readProducts(parser);
            } else {
                skip(parser);
            }
        }  
        return entry;
    }
    private List<Entry> readProducts(XmlPullParser parser) throws XmlPullParserException, IOException {
        List<Entry> entries = new ArrayList<Entry>();

        parser.require(XmlPullParser.START_TAG, ns, "products");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();
           // Log.i("..................",name);
            // Starts by looking for the products tag
            if (name.equals("product")) {
                entries.add(readEntry(parser));
            } else {
                skip(parser);
            }
        }  
        return entries;
    }
    private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
        parser.require(XmlPullParser.START_TAG, ns, "product");
        String title = null;
        String summary = null;
        String link = null;
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();
           // Log.i("...................",name);
            if (name.equals("id")) {
                title = readId(parser);
            } else if (name.equals("id_default_image")) {
                summary = readLink(parser);
            } else if (name.equals("price")) {
                link = readPrice(parser);
            } else {
                skip(parser);
            }
        }
        return new Entry(title, summary, link);
    }
    private String readPrice(XmlPullParser parser) throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "price");
        String summary = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "price");
        return summary;
    }
    private String readLink(XmlPullParser parser) throws IOException, XmlPullParserException {
        String link = "";
        parser.require(XmlPullParser.START_TAG, ns, "id_default_image");
        String tag = parser.getName();
       // Log.i("............",tag);
        String relType = parser.getAttributeValue(null, "not_filterable");  
        if (tag.equals("id_default_image")) {
            if (relType.equals("true")){
                link = parser.getAttributeValue(null, "xlink:href");
                parser.nextTag();
            } 
        }
        parser.require(XmlPullParser.END_TAG, ns, "id_default_image");
        return link;
    }
    private String readId(XmlPullParser parser) throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "id");
        String title = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "id");
        return title;
    }
    private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
        String result = "";
        if (parser.next() == XmlPullParser.TEXT) {
            result = parser.getText();
            parser.nextTag();
        }
        return result;
    }
    private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            throw new IllegalStateException();
        }
        int depth = 1;
        while (depth != 0) {
            switch (parser.next()) {
            case XmlPullParser.END_TAG:
                depth--;
                break;
            case XmlPullParser.START_TAG:
                depth++;
                break;
            }
        }
     }
    public static class Entry {
        public final String id;
        public final String link;
        public final String price;

        private Entry(String id, String link, String price) {
            this.id = id;
            this.link = link;
            this.price = price;
        }
    }
} 

The log output

12-10 03:29:44.664: I/ID is..........(1511):  5 
12-10 03:29:44.664: I/Link is........(1511): https://www.10ngah.com/api/images/products/5/5
12-10 03:29:44.674: I/Price is.......(1511):  525 
12-10 03:29:44.674: I/ID is..........(1511):  6 
12-10 03:29:44.674: I/Link is........(1511): https://www.10ngah.com/api/images/products/6/6
12-10 03:29:44.674: I/Price is.......(1511):  525 

Solution 2:

First your example has syntax error (missing space before attribute)...

I like a JAXB very much... so I would recomend it to you. If your data has static format (not change format in time) it is the best way. Only "problem" could be with CDATA blocks, see this post for more information. Here is "fast" example... it is not nice code just a example!



    public class AdapterCDATA extends XmlAdapter {


      @Override
      public String marshal(String arg0) throws Exception {
        return "";
      }

      @Override
      public String unmarshal(String arg0) throws Exception {
        return arg0;
      }
    }



    public class TestData {

      @XmlRootElement(name = "prestashop")
      @XmlAccessorType(XmlAccessType.FIELD)
      static class Prestashop {

        @XmlElementWrapper(name = "products")
        @XmlElement(name = "product")
        List products;
      }

      @XmlAccessorType(XmlAccessType.FIELD)
      static class Product {
        @XmlJavaTypeAdapter(AdapterCDATA.class)
        @XmlElement(name = "id")
        String id;

        @XmlElement(name = "id_default_image")
        IdDefaultImage idDefaultImage;

        @XmlJavaTypeAdapter(AdapterCDATA.class)
        @XmlElement(name = "price")
        String price;

        @XmlElement(name = "name")
        Name name;
      }

      @XmlAccessorType(XmlAccessType.FIELD)
      static class IdDefaultImage {
        @XmlAttribute(name = "not_filterable")
        String notFilterable;

        @XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
        String href;

        @XmlJavaTypeAdapter(AdapterCDATA.class)
        @XmlValue
        String idDefaultImage;
      }

      @XmlAccessorType(XmlAccessType.FIELD)
      static class Name {
        @XmlElement(name = "language")
        Language language;
      }

      @XmlAccessorType(XmlAccessType.FIELD)
      static class Language {
        @XmlJavaTypeAdapter(AdapterCDATA.class)
        @XmlValue
        String language;

        @XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
        String href;

        @XmlAttribute(name = "id")
        String id;
      }

      public static void main(String[] args) throws JAXBException {
        JAXBContext jc = JAXBContext.newInstance(Prestashop.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/test/resources/testData.xml");
        Prestashop prestashop = (Prestashop) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(prestashop, System.out);
      }
    }


Solution 3:

EXAMPLE XML:

<a>
<b category='3' number='25' points='2'>
<c>
<d filename='' content='some content'/>
<d filename='0134.jpg'/>
</c>
<e>
<f description='desc' correct='1'/>
</e>
</a>

CODE FOR PARSING
Fields in parsing class to make later modification easier:

//data to parse
private static final String TAG_A = "a";        //root

private static final String TAG_B = "b";
private static final String ATT_CATEGORY = "category";
private static final String ATT_POINTS = "points";

private static final String TAG_D = "d";
private static final String ATT_FILE_NAME = "filename";
private static final String ATT_CONTENT = "content";

private static final String TAG_F = "f";
private static final String ATT_DESCRIPTION = "description";
private static final String ATT_CORRECT = "correct";

Method in parsing class:

    private void parseXml()
    {
        try
        {
            XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            parser.setInput(questionsXmlFile, null);
            parser.nextTag();
            parser.require(XmlPullParser.START_TAG, null, TAG_A);
            while (parser.next() != XmlPullParser.END_DOCUMENT)
            {
                if (parser.getEventType() == XmlPullParser.START_TAG)
                {
                    String name = parser.getName();
                    if (name.equalsIgnoreCase(TAG_B))
                    {
                        parser.getAttributeValue(null, ATT_CATEGORY));
                        parser.getAttributeValue(null, ATT_POINTS));
                    }
                    else if (name.equalsIgnoreCase(TAG_D))
                    {
                        parser.getAttributeValue(null, ATT_CONTENT));
                        parser.getAttributeValue(null, ATT_FILE_NAME));
                    }
                    else if (name.equalsIgnoreCase(TAG_ANSWER))
                    {
                    }
                }
            }
        }
        catch (XmlPullParserException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

What this method does? It traverse through xml from beginning to END_DOCUMENT and check if tags has been found are interesting one. If yes, check desired attributes and do nothing with it (add your own actions.
Remember, getAttributeValue() can return null. Be sure you dont operate on null.
Remember, parser.require(XmlPullParser.START_TAG, null, TAG_A) returns exception if variables passed to it are wrong comparing current situation of parser.


Solution 4:

Your code looks all ok, only you have to remove <![CDATA[ .... ]]>

<id><![CDATA[ 526 ]]></id> change to <id>526</id>

or if you do not want to remove it, then do it following way,

Add the following method/function:

public String getCDataValue(Element e, String id) {
        NodeList title = e.getElementsByTagName(id);
        Element ex = (Element) title.item(0);
        Node child = ex.getFirstChild();
        if (child instanceof CharacterData) {
            CharacterData cd = (CharacterData) child;
            return cd.getData().trim();
        }
        return "";
}

and then use it this way:

NodeList nl = doc.getElementsByTagName("product");
       for (int i = 0; i < nl.getLength(); i++) {
        Element e = (Element) nl.item(i);
        Toast.makeText(getApplicationContext(), getCDataValue(e, "price"),
        Toast.LENGTH_SHORT).show();
}

if its is your code :

publishProgress(new ProductItems(
                      getCDataValue(e, "name"),
                      getCDataValue(e, "id"),
                      getCDataValue(e, "id_default_image"),
                      12.050000)
);

Post a Comment for "Trouble With Xml Parsing Through JAVA"