More an more mobile devices are used to access Internet and connected services. One efficient way to transfer data between different platforms and technologies is to use XML files, which are simple text files formatted accordingly to the XML rules.
IN order to process an XML file and to extract needed data you need a XML parser which is a text process engine.
The problem for J2ME MIDlets is that there are mobile devices that don’t support the XML API for Java ME additional package (JSR 280). In order to solve this problem, we need an independent and lightweight XML parser that must be fast and with a small impact on the memory. Two possible solutions are kXML and NanoXML.
In the next MIDlet example (You can download the full source code, including a sample test MIDlet), we will use kXML to parse a RSS feed, the itcsolutions.eu RSS feed.
How to use kXML
In order to understand how to:
- install kXML in your NetBeans J2ME project;
- use methods from org.kxml2.io.KXmlParser class;
check How to use kXML to parse XML files in J2ME projects post.
How to access a Web based XML document from a MIDlet
In order to access a XML document on the Web, we need a HttpConnection object. Once we get an active connection, we can process the XML at byte or char level.
For processing the remote XML at char level, we need an InputStreamReader (it will be created based on the InputStream object). This will be the input for the kXML parser.
Because operations that require network access can block the main thread, the entire procedure of getting the XML file from the given URL and parsing it, will be executed in a secondary thread. This will prevent the application to block and it will allow users to use the application commands like Exit. Other wise, the main thread will wait for the network operation to end in order to execute command handlers.
The method that handles the HTTP connection is getXMLFeed():
public void getXMLFeed(final String url) { Thread t = new Thread() { public void run() { HttpConnection myConnection = null; try { //open the connection myConnection = (HttpConnection) Connector.open(url); //get the bytes stream InputStream stream = myConnection.openInputStream(); //call the parsing method ParseXMLFeed(stream); } catch (Exception error) { parentMidlet.DisplayError(error); } finally { //close the connection try { if (myConnection != null) { myConnection.close(); } } catch (IOException eroareInchidere) { //calls a method from the MIDlet that display an alert parentMidlet.DisplayError(eroareInchidere); } } } }; //starts the thread t.start(); }
How to parse the RSS feed using the kXML parser
In order to use the kXML parser you must:
- know the XML document structure; in this example, the XML is the itcsolutions.eu RSS feed;
- know how the kXML methods: How to use kXML to parse XML files in J2ME projects;
The method that implements the XML parsing is ParseXMLFeed():
- the method argument is an InputStream reference; this will be used to create a Reader reference needed to process the XML at char level and also needed to define the input for the kXmlParser.
- the method extracts only the title and the link for each RSS item; the data is stored in a News (class defined in the utility package) item; the News item is added in a Vector defined at MIDlet level using the midlet addNews() method;
The steps that define the process of parsing the XML feed are:
- create and initialize the KXmlParser using the InputStreamReader provided by the HttpConnection;
- because the <item> nodes are sub-nodes of <channel> and we want to process them in a iterative way, we must go past <rss> into <channel> sub-nodes collection;
- loop through the nodes using nextTag() method and for each <item> start tag, get the title and the link; the title and the link are used to create a News object that is added to the Vector collection of the Midlet;
- for any other node than <item> skip it and its details using skipSubTree() method;
- when we reach a <channel> node, it means we have finished its sub-tree because this is the end tag;
private void ParseXMLFeed(InputStream input) throws IOException, XmlPullParserException { Reader dataReader = new InputStreamReader(input); //kXML parser KXmlParser myParser = new KXmlParser(); myParser.setInput(dataReader); //skip the first node - rss myParser.nextTag(); myParser.require(XmlPullParser.START_TAG, null, "rss"); //skip the second node - channel myParser.nextTag(); myParser.require(XmlPullParser.START_TAG, null, "channel"); myParser.nextTag(); myParser.require(XmlPullParser.START_TAG, null, "title"); while (myParser.getEventType() != XmlPullParser.END_DOCUMENT) { String name = myParser.getName(); //this is for reaching the end tag for channel node if (name.equals("channel")) { break; } //this is for each item node in the RSS feed if (name.equals("item")) { //process it only if it is reached the start tag if (myParser.getEventType() != XmlPullParser.END_TAG) { myParser.nextTag(); String title = myParser.nextText(); myParser.nextTag(); String link = myParser.nextText(); //create a new News item News news = new News(title, link); parentMidlet.addNews(news); } } else { //if it is not the item node the skip it and all its details myParser.skipSubTree(); } //move to the next tag myParser.nextTag(); } //close the input stream - job done input.close(); }
How is working the mobile application
- the application is managing the RSS feed items (only the title and the link) using a Vector collection of News objects, news;
- the title of each News object is displayed in a List type form, myNewsList;
- in order to add elements to the Vector collections, the MIDlet provide a public method addNews(); the method also set the List form, myNewsList, as the current one;
//method called by the parsing thread public void addNews(News newsItem){ news.addElement(newsItem); myNewsList.append(newsItem.getTitle(),null); myDysplay.setCurrent(myNewsList); }
- the application has 2 commands: one for closing the application, cmdExit, and one, cmdDetails, for displaying in a Alert details (the link) of the selected title;
public void commandAction(Command command, Displayable displayable) { if(command == cmdExit){ destroyApp(false); notifyDestroyed(); } else if(command == cmdDetails || command == List.SELECT_COMMAND){ //get the index of the selected title int index = myNewsList.getSelectedIndex(); if(index!=-1) { //get the Vector element at that index - News object News newsItem = (News)news.elementAt(index); //display the link in an Alert Alert message = new Alert(newsItem.getTitle(), newsItem.getLink(), null, null); message.setTimeout(Alert.FOREVER); myDysplay.setCurrent(message,myNewsList); } else return; } }
the MIDlet has 2 threads; the main one which is used to display the List form and to manage the 2 commands; the second thread implements the parsing process; the second thread starts when the getXMLFeed() method is called;
public void startApp() { myNewsList.setCommandListener(this); //the XML file url String url = "http://www.itcsolutions.eu/feed/"; ParseThread myThread = new ParseThread(this); //this will start the second thread myThread.getXMLFeed(url); Display.getDisplay(this).setCurrent(myNewsList); }
The main screens of the MIDlet are:

RSS titles list

RSS title details
You can download the full source code, including a sample test MIDlet.

in romanian
in english
#1 by Ratnesh on August 28th, 2011
Well i am trying to build this application but i am facing some problem . I am getting exception ¨Uncaught Exception java/lang/NoClassDefFoundError: org/kxml2/io/KXmlParser¨
i had used Kxml2 jar … I need help urgently.
#2 by Catalin on August 29th, 2011
Hi Ratnesh,
Have you added the kxml library to your J2ME project ? If yes, have you downloaded and tested the sample application from the post ?
If the sample application is working but not your project please show me the import statements and the statement that generates the error.
#3 by Andre on September 4th, 2011
Hi, Please can you assist me in my project, i am building a J2ME application that has a news, forex and weatherapps in one midlet, i intend using your Rss feed example for the news area, i hav eused the VMD as the main form and i will want to link it to your sample midlet but in the sam eproject, how do i link them?
Thanks
#4 by Catalin on September 10th, 2011
Hi Andre,
It is simple to import the code sample into your project:
1. download and open the zip archive
2. copy the 2 files from the \eu\itcsolutions\rssparser\utility folder into your project directory
3. edit the 2 files and change the package name based on your own package structure (modify the package eu.itcsolutions.rssparser.utility; declaration)
4. as you already have a Midlet, create a new class that extends List and copy most of the XMLMidlet.java in the new class (code from startApp() can go in the class constructor)
If you still have problems, I can give you the class from step 4.
#5 by Tung on October 17th, 2011
Hi, i make a j2me app, it runs very well but when i built with obfuscate, it cannot get data from internet.