この XML を解析するために SAX を使用すると、複数のリンクの href 属性値を取得する方法がわかりません。以下の私の例では、ログはリンク URL にnullを示しています。(タイトル: これはタイトルです リンク: null)
<entry>
<title>This is the title</title>
<summary>This is a test summary of the article</summary>
<link rel="alternate" type="text/html" href="http://www.demo.com" />
<link rel="enclosure" href="http://www.demo.com/demo.jpg"/>
</entry>
RssParseHandler.java
public class RssParseHandler extends DefaultHandler {
private ArrayList<RssItem> rssItems;
// Used to reference item while parsing
private RssItem currentItem;
// Parsing title indicator
private boolean parsingTitle;
// Parsing description indicator
private boolean parsingDescription;
// Parsing link indicator
private boolean parsingLink;
// Parsing image indicator
private boolean parsingImage;
StringBuilder obj;
public RssParseHandler() {
rssItems = new ArrayList<RssItem>();
}
public ArrayList<RssItem> getItems() {
return rssItems;
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
obj = new StringBuilder();
if ("entry".equals(qName)) {
currentItem = new RssItem();
} else if ("title".equals(qName)) {
parsingTitle = true;
} else if ("summary".equals(qName)) {
parsingDescription = true;
} else if ("link".equals(qName)) {
String LinkType = attributes.getValue("rel");
if (LinkType.equals("alternate")) {
parsingLink = true;
} else if (LinkType.equals("enclosure")) {
parsingImage = true;
}
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
String result = obj.toString();
if ("entry".equals(qName)) {
rssItems.add(currentItem);
currentItem = null;
} else if ("title".equals(qName)) {
parsingTitle = false;
} else if ("summary".equals(qName)) {
currentItem.setDescription(result);
// parsingDescription = false;
} else if (parsingLink) {
parsingLink = false;
} else if (parsingImage) {
parsingImage = false;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (parsingTitle) {
if (currentItem != null)
currentItem.setTitle(new String(ch, start, length));
} else if (parsingDescription) {
if (currentItem != null)
// currentItem.setDescription(new String(ch, start, length));
obj.append(ch, start, length);
} else if (parsingLink) {
if (currentItem != null) {
currentItem.setLinkURL(new String(ch, start, length));
parsingLink = false;
}
} else if (parsingImage) {
if (currentItem != null) {
currentItem.setLinkImg(new String(ch, start, length));
parsingImage = false;
}
}
}
}
RssItem.java
public class RssItem {
// item title
private String title;
// item link url
private String linkURL;
// item link image
private String linkImg;
// item description
private String description;
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 getLinkURL() {
return linkURL;
}
public void setLinkURL(String linkURL) {
this.linkURL = linkURL;
}
public String getLinkImg() {
return linkImg;
}
public void setLinkImg(String linkImg) {
this.linkImg = linkImg;
}
@Override
public String toString() {
return "Title: " + title + " Link: " + linkURL;
}
}
編集
public class ReaderActivity extends Activity {
// A reference to the local object
private RssAdapter adapter;
// private final ArrayList<RssItem> fetch = new ArrayList<RssItem>();
/**
* This method creates main application view
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set view
setContentView(R.layout.main);
GetRSSDataTask task = new GetRSSDataTask();
// Start download RSS task
task.execute("http://www.swtor.com/feed/news/all");
// Debug the thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
}
private class GetRSSDataTask extends
AsyncTask<String, Void, ArrayList<RssItem>> {
@Override
protected ArrayList<RssItem> doInBackground(String... urls) {
// Debug the task thread name
Log.d("ITCRssReader", Thread.currentThread().getName());
try {
// Create RSS reader
RssReader rssReader = new RssReader(urls[0]);
// Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("ITCRssReader", e.getMessage());
}
return null;
}
protected void onPostExecute(ArrayList<RssItem> result) {
// Get a ListView from main view
ListView itcItems = (ListView) findViewById(R.id.listMainView);
// Create a list adapter
// ArrayAdapter<RssItem> adapter = new
// ArrayAdapter<RssItem>(local,android.R.layout.simple_list_item_1,
// result);
// Set list adapter for the ListView
// itcItems.setAdapter(adapter);
adapter = new RssAdapter(ReaderActivity.this,
R.id.listMainView, result);
itcItems.setAdapter(adapter);
// Set list view item click listener
// itcItems.setOnItemClickListener(new ListListener(result, local));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_server:
Intent i = new Intent(this, ServerActivity.class);
startActivity(i);
// app icon in action bar clicked; go home
break;
case R.id.menu_refresh:
Toast.makeText(getApplicationContext(), "Refresh!", Toast.LENGTH_SHORT).show();
// app icon in action bar clicked; go home
break;
}
return true;
}
}
これは私のログです
06-16 21:45:11.943: D/ITCRssReader(6478): main
06-16 21:45:11.943: D/ITCRssReader(6478): AsyncTask #1
06-16 21:45:11.998: D/libEGL(6478): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
06-16 21:45:12.013: D/libEGL(6478): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
06-16 21:45:12.013: D/libEGL(6478): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
06-16 21:45:12.068: D/OpenGLRenderer(6478): Enabling debug mode 0
06-16 21:45:12.474: W/dalvikvm(6478): threadid=11: thread exiting with uncaught exception (group=0x40fe7930)
06-16 21:45:12.482: E/AndroidRuntime(6478): FATAL EXCEPTION: AsyncTask #1
06-16 21:45:12.482: E/AndroidRuntime(6478): java.lang.RuntimeException: An error occured while executing doInBackground()
06-16 21:45:12.482: E/AndroidRuntime(6478): at android.os.AsyncTask$3.done(AsyncTask.java:299)
06-16 21:45:12.482: E/AndroidRuntime(6478): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
06-16 21:45:12.482: E/AndroidRuntime(6478): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
06-16 21:45:12.482: E/AndroidRuntime(6478): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
06-16 21:45:12.482: E/AndroidRuntime(6478): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-16 21:45:12.482: E/AndroidRuntime(6478): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
06-16 21:45:12.482: E/AndroidRuntime(6478): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
06-16 21:45:12.482: E/AndroidRuntime(6478): at java.lang.Thread.run(Thread.java:856)
06-16 21:45:12.482: E/AndroidRuntime(6478): Caused by: java.lang.NullPointerException: println needs a message
06-16 21:45:12.482: E/AndroidRuntime(6478): at android.util.Log.println_native(Native Method)
06-16 21:45:12.482: E/AndroidRuntime(6478): at android.util.Log.e(Log.java:231)
06-16 21:45:12.482: E/AndroidRuntime(6478): at com.stryksta.swtorcentral.ReaderActivity$GetRSSDataTask.doInBackground(ReaderActivity.java:71)
06-16 21:45:12.482: E/AndroidRuntime(6478): at com.stryksta.swtorcentral.ReaderActivity$GetRSSDataTask.doInBackground(ReaderActivity.java:1)
06-16 21:45:12.482: E/AndroidRuntime(6478): at android.os.AsyncTask$2.call(AsyncTask.java:287)
06-16 21:45:12.482: E/AndroidRuntime(6478): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
06-16 21:45:12.482: E/AndroidRuntime(6478): ... 4 more