0

当我使用 SAX 解析这个 XML 时,我不知道如何获取多个链接的 href 属性值。在下面的示例中,thelog在链接 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
4

1 回答 1

0

您的解析代码假定 url 以字符数据的形式出现,如标题。它们不是在您的 xml 中以这种方式给出的,而是作为<link>标记上的附加属性。

所以你需要在你的方法中解析href属性startElement

@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");
        String url = attributes.getValue("href");
        if (LinkType.equals("alternate")) {
            currentItem.setLinkURL(url);
        } else if (LinkType.equals("enclosure")) {
            currentItem.setLinkImg(url);
        }
    }
}

而且您不需要parsingLinkand字段或and方法parsingImage中的那部分逻辑。charactersendElement

于 2013-06-17T00:22:37.437 回答