Android DOM parsing
I have a rss xml data from the link http://itunes.apple.com/us/rss/topsongs/limit=10/xml;
<entry>
<updated>2011-07-06T23:07:06-07:00</updated>
<id>http://itunes.apple.com/us/album/party-rock-anthem-feat-lauren/id440148435?i=440148440&uo=2&uo=2</id>
<title>Party Rock Anthem (feat. Lauren Bennett & GoonRock) - LMFAO</title>
<im:name>Party Rock Anthem (feat. Lauren Bennett & GoonRock)</im:name>
<link rel="alternate" type="text/html" href="http://itunes.apple.com/us/album/party-rock-anthem-feat-lauren/id440148435?i=440148440&uo=2&uo=2"/>
<im:contentType term="Music" label="Music">
<im:contentType term="Track" label="Track"/>
</im:contentType>
<category term="Pop" scheme="http://itunes.apple.com/us/genre/music-pop/id14?uo=2" label="Pop"/>
<link title="Preview" rel="enclosure" type="audio/x-m4a" href="http://a1.mzstatic.com/us/r1000/008/Music/6d/e2/e7/mzi.vmmixjty.aac.p.m4a" im:assetType="preview">
<im:duration>30000</im:duration>
</link>
<im:artist href="http://itunes.apple.com/us/artist/lmfao/id284482668?uo=2">LMFAO</im:artist>
<im:price amount="1.29000" currency="USD">$1.29</im:price>
<im:image height="55">http://a5.mzstatic.com/us/r1000/037/Music/3c/0c/ba/mzi.levtcsmk.55x55-70.jpg
</im:image>
<im:image height="60">http://a2.mzstatic.com/us/r1000/037/Music/3c/0c/ba/mzi.levtcsmk.60x60-50开发者_如何学Go.jpg
</im:image>
<im:image height="170">http://a3.mzstatic.com/us/r1000/037/Music/3c/0c/ba/mzi.levtcsmk.170x170-75.jpg
</im:image>
<rights>2011 Interscope Records</rights>
<im:releaseDate label="June 21, 2011">2011-06-21T00:00:00-07:00</im:releaseDate>
<im:collection>
<im:name>Sorry for Party Rocking (Deluxe Version)</im:name>
<link rel="alternate" type="text/html" href="http://itunes.apple.com/us/album/sorry-for-party-rocking-deluxe/id440148435?uo=2&uo=2"/>
<im:contentType term="Music" label="Music">
<im:contentType term="Album" label="Album"/>
</im:contentType>
</im:collection>
</entry>
Now, I would like to parse this xml to receive some useful information such as, image url for the one which has height attribute of "170", title, updated at date using DOM.
I can understand how DOM works but while parsing using some DOM methods, I gives crash. I know DOM model in Java is almost similar to getting the element/attributes in javascript. But since I could not get it into my head, I find it difficult to tackle such issues.
My code looks like,
URL url = new URL("http://itunes.apple.com/us/rss/topsongs/limit=10/xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("entry");
for(int i=0; i<nodeList.getLength();i++){
Node node = nodeList.item(i);
Element fstElement = (Element)node;
NodeList title = fstElement.getElementsByTagName("im:image");
Element titleElement = (Element)title.item(2);
Log.d("DOM Element", ((Node)titleElement).getNodeValue());
Log.d("DOM Element", titleElement.getAttribute("height"));
}
How do I fetch the node value of the image, here. I could check to see if the 'height' attribute is equal to '170' but I could not fetch the node value here.
Crash log looks :
W/dalvikvm( 289): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
E/AndroidRuntime( 289): FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime( 289): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime( 289): at android.os.AsyncTask$3.done(AsyncTask.java:200)
E/AndroidRuntime( 289): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
E/AndroidRuntime( 289): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
E/AndroidRuntime( 289): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
E/AndroidRuntime( 289): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime( 289): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
E/AndroidRuntime( 289): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
E/AndroidRuntime( 289): at java.lang.Thread.run(Thread.java:1096)
E/AndroidRuntime( 289): Caused by: java.lang.NullPointerException: println needs a message
E/AndroidRuntime( 289): at android.util.Log.println_native(Native Method)
E/AndroidRuntime( 289): at android.util.Log.d(Log.java:122)
E/AndroidRuntime( 289): at com.android.DOMParser.DOMParser.ParseXML(DOMParser.java:43)
E/AndroidRuntime( 289): at com.android.DOMParser.DOMParser.doInBackground(DOMParser.java:55)
E/AndroidRuntime( 289): at com.android.DOMParser.DOMParser.doInBackground(DOMParser.java:1)
E/AndroidRuntime( 289): at android.os.AsyncTask$2.call(AsyncTask.java:185)
E/AndroidRuntime( 289): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
E/AndroidRuntime( 289): ... 4 more
W/ActivityManager( 59): Force finishing activity com.android.DOMParser/.MainActivity
I/ARMAssembler( 59): generated scanline__00000077:03515104_00000000_00000000 [ 33 ipp] (47 ins) at [0x356768:0x356824] in 1003390 ns
I don't know what object did you use to try to parse the included XML, but you can try with free and open source JSOUP library (http://jsoup.org) that you can include in your android project. It handles nice even with bad formated XML and HTML files...
Here is a simple example from there web site, that explains how to iterate some DOM nodes:
File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/");
Element content = doc.getElementById("content");
Elements links = content.getElementsByTag("a");
for (Element link : links) {
String linkHref = link.attr("href");
String linkText = link.text();
}
I got the answer. I did it like this to store all the data into an ArrayList,
public class DOMParser extends AsyncTask<String[], Long, ArrayList<MyData>> {
private String urlString;
private Context ct;
ProgressDialog dialog;
public DOMParser(Context context, String stringURL) {
urlString = stringURL;
ct = context;
}
ArrayList<MyData> ParseXML() throws ParserConfigurationException,
SAXException, IOException {
ArrayList<MyData> collection = new ArrayList<MyData>();
MyData mydata = new MyData();
URL url = new URL(urlString);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
int j;
NodeList entries = doc.getElementsByTagName("entry");
for (int i = 0; i < entries.getLength(); i++) {
j = 1;
Element entry = (Element) entries.item(i);
NodeList children = entry.getChildNodes();
for (int k = 0; k < children.getLength(); k++) {
Node child = children.item(k);
if ((child.getNodeName().equalsIgnoreCase("title"))
|| (child.getNodeName().equalsIgnoreCase("im:artist"))
|| (child.getNodeName().equalsIgnoreCase("im:price"))
|| ((child.getNodeName().equalsIgnoreCase("im:image")) && (((Element) child)
.getAttribute("height"))
.equalsIgnoreCase("170"))
|| (child.getNodeName()
.equalsIgnoreCase("im:releaseDate"))) {
Log.d(child.getNodeName(), child.getTextContent());
switch (j) {
case 1:
mydata.mTitle = child.getTextContent();
break;
case 2:
mydata.mArtist = child.getTextContent();
break;
case 3:
mydata.mPrice = child.getTextContent();
break;
case 4:
mydata.mImage = child.getTextContent();
break;
case 5:
mydata.mReleaseDate = child.getTextContent();
break;
}
j++;
if (j == 6) {
j = 1;
collection.add(mydata);
mydata = new MyData();
}
}
}
}
return collection;
}
@Override
protected ArrayList<MyData> doInBackground(String[]... arg0) {
ArrayList<MyData> Collection = null;
try {
Collection = ParseXML();
} 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 Collection;
}
@Override
protected void onPostExecute(ArrayList<MyData> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
for (MyData mydatas : result) {
Log.d("Each", mydatas.mTitle);
}
}
}
精彩评论