XmlPullParser считывает значение null, если следующий тег находится в новой строке

Я пытаюсь сделать rss-ридер с помощью xmlpullparser. Допустим, у меня есть такой xml-файл:

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
 <channel>
 <title>RSS Title</title>
 <description>This is an example of an RSS feed</description>
 <link>http://www.someexamplerssdomain.com/main.html</link>
 <lastBuildDate>Mon, 06 Sep 2010 00:01:00 +0000 </lastBuildDate>
 <pubDate>Mon, 06 Sep 2009 16:20:00 +0000 </pubDate>
 <ttl>1800</ttl>

 <item>
  <title>Example entry</title>
  <description>Here is some text containing an interesting description.</description>
  <link>http://www.wikipedia.org/</link>
  <guid>unique string per item</guid>
  <pubDate>Mon, 06 Sep 2009 16:20:00 +0000 </pubDate>
 </item>

 </channel>
</rss>

Когда я пытаюсь его прочитать, он читает тег rss, а затем, перед чтением канала, читает ноль. Переместите тег канала рядом с тегом rss, например:

<rss version="2.0"><channel>
<title>...

У меня больше нет этой проблемы, но я не могу этого сделать, потому что я не хочу читать только свои xml-файлы.

Это часть кода, который я использую:

public Feed rss() throws XmlPullParserException, IOException {
        matchStart(Tag.rss);
        move();
        Feed channel = channel();
        matchEnd(Tag.rss);

        return channel;
    }

    private Feed channel() throws XmlPullParserException, IOException {
        matchStart(Tag.channel);
        move();

        String title = null;
        String link = null;
        String description = null;
        String pubDate = null;
        List<FeedMessage> items = new ArrayList<FeedMessage>();

        while(eventType != XmlPullParser.END_TAG) {
            if(xmlParser.getEventType() != XmlPullParser.START_TAG) {   //Look if we are checking an open tag <tag> if not es</tag> then go to the next one
                move();
                continue;
            }

            String name = xmlParser.getName();
            switch(name) {
                case Tag.title: title = title(); break;
                case Tag.link: link = link(); break;
                case Tag.description: description = description(); break;
                case Tag.pubDate: pubDate = pubDate(); break;
                case Tag.item: items.add(item()); break;
                default: skip(); break;
            }

            move();
        }

        Feed channel = new Feed(title, link, description, pubDate, items);

        matchEnd(Tag.channel);

        return channel;
    }

где matchStart и matchEnd вызывают xmlParser.require, чтобы проверить START_TAG и END_TAG и переместить его, как это определено следующим образом:

void move() throws XmlPullParserException, IOException {
        eventType = xmlParser.next();
    }

Я не могу найти, в чем проблема, что-то не так с кодом или логикой?


person ChiP    schedule 21.12.2013    source источник


Ответы (2)


Когда у вас есть новая строка, событие next после открывающего тега rss является не тегом канала, а событием TEXT, представляющим эту новую строку и отступ перед тегом канала. Вам нужно продолжать пропускать, пока вы не нажмете следующее событие начального тега после <rss>, точно так же, как вы уже делаете в основном цикле внутри channel().

person Ian Roberts    schedule 21.12.2013
comment
спасибо, чувак, это была проблема, которую я не знал о текстовом событии, представляющем новую строку, теперь оно работает так, как должно. - person ChiP; 21.12.2013
comment
@ChiP синтаксический анализатор может пропускать игнорируемые пробелы, но чтобы узнать, какие пробелы на самом деле игнорируются, документ должен ссылаться на DTD, а синтаксический анализатор должен находиться в режиме проверки. Без DTD синтаксический анализатор не может знать, какие пробелы значимы, а какие нет, поэтому он должен перестраховаться и сообщить обо всем. - person Ian Roberts; 21.12.2013

попробуйте этот код

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser xpp = factory.newPullParser();
        factory.setNamespaceAware(false);
        xpp.setInput(new StringReader(xml));

        int eventType = xpp.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) 
        {

            if (eventType == XmlPullParser.START_TAG) 
            {

                if (xpp.getName().equalsIgnoreCase("item")) 
                {
                    insideItem = true;
                } 
                else if (xpp.getName().equalsIgnoreCase("title")) 
                {
                    if (insideItem)
                    {
                   String s=xpp.nextText();
                   System.out.println("-----item title"+s);
                    normalHeadlines.add(s); // extract the// headline
                    }
                } 
                else if (xpp.getName().equalsIgnoreCase("link")) 
                {
                    if (insideItem)
                        normallinks.add(xpp.nextText()); // extract the link of
                                                    // article
                }
                else if (xpp.getName().equalsIgnoreCase("pubDate")) 
                {
                    if (insideItem)
                        normaldates.add(xpp.nextText()); // extract the link of
                                                    // article
                }

                else  if(xpp.getName().equalsIgnoreCase("description"))
                {
                    if (insideItem)
                    {
                    String s=xpp.nextText();
                    normaldescription.add(s);
                    separationImage(s);                 
                    }
                }
            } 
            else if (eventType == XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")) 
            {
                insideItem = false;
            }

            eventType = xpp.next(); // move to next element
        }
person skyshine    schedule 21.12.2013