只能解析TITLE标记 - LINK,DESCRIPTION,PUBDATE等不会解析。 (RSS / SAX)

时间:2014-12-09 02:45:51

标签: parsing tags sax podcast

我是Android开发的新手,我一直在努力解析多个标签并将其显示在ListView中。

我使用的是SAX解析器,这是我的RssParseHandler代码。

public class RssParseHandler extends DefaultHandler {
private List<RssItem> rssItems;
private RssItem currentMessage;
//private StringBuilder builder;
private boolean parseLink;
private boolean parseTitle;
private boolean parseDate;
private boolean parseDes;

public RssParseHandler() {
    rssItems = new ArrayList();
}

public List<RssItem> getItems() {


    return this.rssItems;
}


@Override
public void startElement(String uri, String localName, String name,
                         Attributes attributes) throws SAXException {
    super.startElement(uri, localName, name, attributes);
    if (localName.equalsIgnoreCase("item")) {
        this.currentMessage = new RssItem();
    } else if (localName.equalsIgnoreCase("title")) {
        //currentMessage.setTitle(builder.toString());
        parseTitle = true;
    } else if (localName.equalsIgnoreCase("link")) {
        //currentMessage.setLink(builder.toString());
        parseLink = true;
    } else if (localName.equalsIgnoreCase("description")) {
        //currentMessage.setDescription(builder.toString());
       parseDes = true;
        } else if (localName.equalsIgnoreCase("pubDate")) {
        //currentMessage.setDate(builder.toString());

        parseDate = true;
    }

    //parsing enclosure tag
    else if ("enclosure".equals(localName)) {
        // Get tags attributes number
        int attrsLength = attributes.getLength();
        for (int i = 0; i < attrsLength; i++) {
            String attrName = attributes.getQName(i);  // attribute name
            if ("url".equals(attrName))   // This tag has only one attribute but it is better to check it name is correct
                currentMessage.getLink();

        }

    }
}


@Override
public void endElement(String uri, String localName, String name)
        throws SAXException {


    super.endElement(uri, localName, name);
    if (this.currentMessage != null) {
        if (localName.equalsIgnoreCase("item")) {
            rssItems.add(currentMessage);
            //currentMessage = null;
        } else if (localName.equalsIgnoreCase("link")) {
            //currentMessage.setLink(builder.toString());
            //parseLink = false;
       } else if (localName.equalsIgnoreCase("description")) {
            //currentMessage.setDescription(builder.toString());
          //parseDes = false;
        } else if (localName.equalsIgnoreCase("pubDate")){

            //currentMessage.setDate(builder.toString());
            parseDate = false;
        } else if (localName.equalsIgnoreCase("title")) {
            //currentMessage.setTitle(builder.toString());
            parseTitle = false;
        }
        //builder.setLength(0);
    }
}

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    super.characters(ch, start, length);
    //builder.append(ch, start, length);
    if (parseTitle) {
        if (currentMessage != null)
            currentMessage.setTitle(new String(ch, start, length));

    } else if (parseLink) {
        if (currentMessage != null) {
            currentMessage.setLink(new String(ch, start, length));
            //parseLink = false;
        }
    } else if (parseDes) {
        if (currentMessage != null)
            currentMessage.setDescription(new String(ch, start, length));
            //parseLink = false;


    } else if (parseDate) {
        if (currentMessage != null) {
            currentMessage.setDate(new String(ch, start, length));
            //currentMessage.setDate(new String(ch, start, length));
            //parseDesc = false;
        }
        }
    }

}

以下是Listview的代码:

public class ReaderAppActivity extends Fragment {

    private ReaderAppActivity local;
    private ListView mList;
    /**
     * This method creates main application view
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        //super.onCreate(savedInstanceState);
        // Set view
        //setContentView(R.layout.fragment_rss);





        local = this;
        //int position = getArguments().getInt("position");

       // String url = getArguments().getString("url");

        // List of rivers
        String[] menus = getResources().getStringArray(R.array.menus);

        // Creating view corresponding to the fragment
        View v = inflater.inflate(R.layout.fragment_rss, container, false);
        // Set reference to this activity
        //local = this;

        GetRSSDataTask task = new GetRSSDataTask();

        // Start download RSS task
        task.execute("http://thechurchofwhatshappeningnow.libsyn.com/rss");
        //task.execute(url);

        // Debug the thread name
        Log.d("ITCRssReader", Thread.currentThread().getName());

        //mList = (ListView) findViewById(R.id.rssListMainView);

        return v;
    }

    private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem> > {
        @Override
        protected List<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;
        }

        @Override
        protected void onPostExecute(List<RssItem> result) {

            // Get a ListView from main view
            ListView mList = (ListView) getView().findViewById(R.id.rssListMainView);

            // Create a list adapter
            ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.rss_text, result);
            //ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.fragment_rss, result);
            // Set list adapter for the ListView
            mList.setAdapter(adapter);

            // Set list view item click listener
            mList.setOnItemClickListener(new ListListener(result, getActivity()));




        }
    }
}

我做错了什么?我无法弄明白。我想解析,链接,描述,pubDate,并将它们传递给ListView。理想情况下,我只会在列表视图中显示标题和剧集编号,并将其他标记传递给String,因此当我单击listView中的项目时,我可以显示它们。

当我点击ListView中的某个项目时,我已经创建了另一个名为SingleMenuItem的类,它现在只是填充代码,它没有显示任何内容,因为项目没有被解析

任何帮助将不胜感激。 Here is a RSS link to the feed:

public class SingleMenuItem  extends Activity {

    // XML node keys
    static final String KEY_NAME = "name";
    static final String KEY_DATE = "pubdate";
    static final String KEY_DESC = "description";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.single_list_item);

        // getting intent data
        Intent in = getIntent();

        // Get XML values from previous intent
        String name = in.getStringExtra(KEY_NAME);
        String date = in.getStringExtra(KEY_DATE);
        String description = in.getStringExtra(KEY_DESC);

        // Displaying all values on the screen
        TextView lblName = (TextView) findViewById(R.id.name_label);
        TextView lblDate = (TextView) findViewById(R.id.date_label);
        TextView lblDesc = (TextView) findViewById(R.id.description_label);

        lblName.setText(name);
        lblDate.setText(date);
        lblDesc.setText(description);
    }
}

以下是我的ReaderAppActivty的代码,它将解析的结果放入ListView:

public class ReaderAppActivity extends Fragment {

private ReaderAppActivity local;
private ListView mList;
/**
 * This method creates main application view
 */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    //super.onCreate(savedInstanceState);
    // Set view
    //setContentView(R.layout.fragment_rss);





    local = this;
    //int position = getArguments().getInt("position");

   // String url = getArguments().getString("url");

    // List of rivers
    String[] menus = getResources().getStringArray(R.array.menus);

    // Creating view corresponding to the fragment
    View v = inflater.inflate(R.layout.fragment_rss, container, false);
    // Set reference to this activity
    //local = this;

    GetRSSDataTask task = new GetRSSDataTask();

    // Start download RSS task
    task.execute("http://thechurchofwhatshappeningnow.libsyn.com/rss");
    //task.execute(url);

    // Debug the thread name
    Log.d("ITCRssReader", Thread.currentThread().getName());

    //mList = (ListView) findViewById(R.id.rssListMainView);

    return v;
}

private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem> > {
    @Override
    protected List<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;
    }

    @Override
    protected void onPostExecute(List<RssItem> result) {

        // Get a ListView from main view
        ListView mList = (ListView) getView().findViewById(R.id.rssListMainView);

        // Create a list adapter
        ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.rss_text, result);
        //ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(getActivity(),R.layout.fragment_rss, result);
        // Set list adapter for the ListView
        mList.setAdapter(adapter);

        // Set list view item click listener
        mList.setOnItemClickListener(new ListListener(result, getActivity()));




    }
}

}

1 个答案:

答案 0 :(得分:0)

根据您RssParseHandler中已注释掉的代码数量,您显然已经在努力解决这个问题了,而且一些早期尝试比您现在所做的更接近正确。

您当前代码的问题似乎是您没有始终重置驱动您正在设置项目的哪一部分的布尔值。通过它进行调试,我看到它在某个时刻在链接字段中设置了一个日期。

但是你实际上是在错误的方法中做了一些设置,因为characters方法不一定会给你标签的全部内容。您需要使用Stringbuilder,我可以在注释掉的代码中看到您在某些时候尝试过这种情况。

如果您在stringbuilder中收集文本并执行endElement方法中的所有设置,则根本不需要布尔值,因为endElement方法知道您使用哪个标记'结束。

这是一个工作版本,可能与你在某些时候所拥有的东西相距甚远,但它摆脱了所有这些旗帜领域。

public class RssParseHandler extends DefaultHandler {
    private List<RssItem> rssItems;
    private RssItem currentMessage;
    private StringBuilder builder;

    public RssParseHandler() {
        rssItems = new ArrayList<>();
        builder = new StringBuilder();
    }

    public List<RssItem> getItems() {
        return this.rssItems;
    }

    @Override
    public void startElement(String uri, String localName, String name,
                             Attributes attributes) throws SAXException {
        super.startElement(uri, localName, name, attributes);
        builder.setLength(0);
        if (localName.equalsIgnoreCase("item")) {
            this.currentMessage = new RssItem();
        }
    }

    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {

        super.endElement(uri, localName, name);
        if (this.currentMessage != null) {
            if (localName.equalsIgnoreCase("item")) {
                rssItems.add(currentMessage);
                currentMessage = null;
            } else if (localName.equalsIgnoreCase("link")) {
                currentMessage.setLink(builder.toString());
            } else if (localName.equalsIgnoreCase("description")) {
                currentMessage.setDescription(builder.toString());
            } else if (localName.equalsIgnoreCase("pubDate")){
                currentMessage.setDate(builder.toString());
            } else if (localName.equalsIgnoreCase("title")) {
                currentMessage.setTitle(builder.toString());
            }
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        super.characters(ch, start, length);
        builder.append(ch, start, length);
    }

}