Android: синтаксический анализ Sax для просмотра списка - PullRequest
1 голос
/ 21 августа 2011

Прежде всего, я новичок в Android и Java .. Я пытался добавить «простое» Rss Reader в мое приложение.Все, что я хочу, это проанализировать RSS-канал с определенного сайта, взять заголовок и дату публикации и поместить эти элементы в просмотр списка, и при щелчке по элементу списка откроется браузер для отображения веб-страницы, содержащей статью.Достаточно легко, верно?Мне грустно говорить, что это поставило меня в тупик на несколько дней.

Я прочитал несколько уроков / примеров, и код, который я пытаюсь изменить в соответствии со своими целями, выглядит следующим образом:
Основная активность

public class News extends Activity {

    private final String MY_DEBUG_TAG = "Some NEWS";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
            super.onCreate(icicle);

            /* Create a new TextView to display the parsingresult later. */
            TextView tv = new TextView(this);
            try {
                    /* Create a URL we want to load some xml-data from. */
                    URL url = new URL("http://www.some.com/feed/");

                    /* Get a SAXParser from the SAXPArserFactory. */
                    SAXParserFactory spf = SAXParserFactory.newInstance();
                    SAXParser sp = spf.newSAXParser();

                    /* Get the XMLReader of the SAXParser we created. */
                    XMLReader xr = sp.getXMLReader();
                    /* Create a new ContentHandler and apply it to the XML-Reader*/ 
                    ExampleHandler myExampleHandler = new ExampleHandler();
                    xr.setContentHandler(myExampleHandler);

                    /* Parse the xml-data from our URL. */
                    xr.parse(new InputSource(url.openStream()));
                    /* Parsing has finished. */

                    /* Our ExampleHandler now provides the parsed data to us. */
                    ParsedExampleDataSet parsedExampleDataSet = 
                                                                    myExampleHandler.getParsedData();

                    /* Set the result to be displayed in our GUI. */
                    tv.setText(parsedExampleDataSet.toTitle());

            } catch (Exception e) {
                    /* Display any Error to the GUI. */
                    tv.setText("Error: " + e.getMessage());
                    Log.e(MY_DEBUG_TAG, "NewsQueryError", e);
            }
            /* Display the TextView. */
            this.setContentView(tv);
    }
}

ExampleHandler

   public class ExampleHandler extends DefaultHandler{

    // ===========================================================
    // Fields
    // ===========================================================

    private boolean in_entry = false;
    private boolean in_id = false;
    private boolean in_title = false;
    private boolean in_updated = false;
    private boolean in_summary = false;
    private boolean in_link = false;

    private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();




    // ===========================================================
    // Getter & Setter
    // ===========================================================

    public ParsedExampleDataSet getParsedData() {
        return this.myParsedExampleDataSet;
    }

    // ===========================================================
    // Methods
    // ===========================================================
    @Override
    public void startDocument() throws SAXException {
        this.myParsedExampleDataSet = new ParsedExampleDataSet();
    }

    @Override
    public void endDocument() throws SAXException {
            // Nothing to do
    }

    /** Gets be called on opening tags like: 
     * <tag> 
     * Can provide attribute(s), when xml was like:
     * <tag attribute="attributeValue">*/
    @Override
    public void startElement(String namespaceURI, String localName,
                    String qName, Attributes atts) throws SAXException {
            if (localName.equals("entry")) {                    
                    this.in_entry = true;
            }else if (localName.equals("id")) {                 
                    this.in_id = true;
            }else if (localName.equals("title")) {
                    this.in_title = true;
            }else if (localName.equals("updated")){
                    this.in_updated = true;
            }else if (localName.equals("summary")) {
                    this.in_summary = true;
            }else if (localName.equals("link")) {
                    this.in_link = true;
            }
    }

    /** Gets be called on closing tags like: 
     * </tag> */
    @Override
    public void endElement(String namespaceURI, String localName, String qName)
                    throws SAXException {
            if (localName.equals("entry")) {
                    this.in_entry = false;
            }else if (localName.equals("id")) {
                    this.in_id = false;
            }else if (localName.equals("title")) {
                    this.in_title = false;
            }else if (localName.equals("updated")) {
                    this.in_updated = false;
            }else if (localName.equals("summary")) {
                    this.in_summary = false;
            }else if (localName.equals("link")) {
                    this.in_link = false;
            }
    }

    /** Gets be called on the following structure: 
     * <tag>characters</tag> */
    public void characters(char ch[], int start, int length) {
        if(this.in_title){
        myParsedExampleDataSet.setextractedTitle(new String(ch, start, length));
}
}
}

ParsedExampleDataSet

public class ParsedExampleDataSet {
    private String extractedId = null;
    private String extractedTitle = null;
    private String extractedUpdated = null;
    private String extractedSummary = null;
    private String extractedImage = null;
    private int extractedInt = 0;

    public String getextractedId() {
            return extractedId;
    }
    public void setextractedId(String extractedId) {
            this.extractedId = extractedId;
    }

    public String getextractedTitle() {
        return extractedTitle;
    }
    public void setextractedTitle(String extractedTitle) {
        this.extractedTitle = extractedTitle;
    }
    public String getextractedUpdated() {
        return extractedUpdated;
    }
    public void setextractedUpdated(String extractedUpdated) {
        this.extractedUpdated = extractedUpdated;
    }

    public String getextractedSummary() {
        return extractedSummary;
    }
    public void setextractedSummary(String extractedSummary) {
        this.extractedSummary = extractedSummary;
    }



    public String toId(){
            return  this.extractedId;
    }

    public String toTitle(){
        return  this.extractedTitle;
    }

    public String toUpdated(){
        return  this.extractedUpdated;
    }

    public String toSummary(){
        return  this.extractedSummary;
    }
}

Теперь, конечно, это просто вернет последнюю запись в ленте.Он анализируется правильно, так как я могу получить каждый элемент, который я хочу отображать по отдельности.Я просто не знаю, как реализовать listveiw.

Заранее спасибо

1 Ответ

2 голосов
/ 21 августа 2011

Давайте сделаем это шаг за шагом, и, надеюсь, мы сможем достичь того, что вы хотите сделать. Я включил соответствующие ссылки на документацию API, которую вы должны знать.

  • Для ListView DOM, вероятно, является более простым выбором, поскольку ListView работает со списком, который прекрасно работает со структурированным списком. Также легче учиться тому, кто плохо знаком с Android и Java. Посмотрите это руководство IBM по XML в разделе "Реализация парсера подачи на основе DOM". Ниже приведен раздел кода, который вы должны учитывать в примере


    DocumentBuilder builder = factory.newDocumentBuilder();
    Document dom = builder.parse(this.getInputStream());
    Element root = dom.getDocumentElement();

  • На данный момент у вас есть данные для вашего ListView . ListView работает с адаптером. Адаптер отвечает за а. Установка начальных данных и б. Показывает, как должен выглядеть каждый ряд. Таким образом, этот класс важен для работы ListView
  • Теперь вы собираетесь создать собственное расширение BaseAdapter , которое будет принимать корневой элемент, который вы получили ранее. Я предоставил класс скелета здесь:

</p>

<pre><code>import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class RSSAdapter extends BaseAdapter {
    Element rootElement;

    public RSSAdapter(Element rootElement) {
        this.rootElement = rootElement;
    }

    public int getCount() {
        // get the count of children of the root element
        return 0;
    }

    public Object getItem(int position) {
        // get the child identified by the position, 
        // this is the important part where you    
        // want to get the right child representing the RSS data that you want to get
        return null;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // implement your view here....
        return null;
    }
}

  • Если вы не знакомы с Element, я предлагаю вам взглянуть на следующую Документацию по Element API . Вам нужно правильно идентифицировать ребенка в функции getItem () выше
  • Теперь вы готовы реализовать метод getView (). Здесь вы бы в основном сделали следующий шаг
    • Получите доступ к нужному дочернему узлу, используя реализованную вами функцию getItem ()
    • Создайте XML-макет для каждой строки и накачайте их здесь. Если вы не знакомы с Android View, посмотрите View API Documentation , так как это важно знать
    • Извлеките данные из дочернего узла и установите для них соответствующий элемент View
  • Далее вам нужно настроить OnItemClickListener в вашем ListView. В слушателе вы захотите снова получить XML с помощью getItem () (этот метод для вас крайне важен) и получить ссылку.
  • Наконец, в реализации onClick () вы хотите использовать WebView и загрузить URL

Этого должно быть достаточно для реализации того, что вы хотите. Я хотел бы уточнить, если шаги не ясны. Надеюсь, это поможет.

...