XMLPullParser getName() возвращает null

Я пытаюсь разобрать openweathermap API http://api.openweathermap.org/data/2.5/weather?q=London&mode=xml. Я использую KXmlParser через XmlPullParserFactory.newPullParser(), но XMLPullParser.getName() всегда возвращает значение null. Это может быть какая-то глупая ошибка, но, похоже, мне может понадобиться ваша помощь, чтобы увидеть это.

Вот код для чтения API через HTTPURLConnection.

 URL url = new URL(urlString);
                URLConnection urlConnection = url.openConnection();
                HttpURLConnection httpConnection = (HttpURLConnection) urlConnection;
                httpConnection.setRequestMethod("GET");
                httpConnection.connect();
                if(httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
                    inputStream = httpConnection.getInputStream();
                }

я использовал

BufferedReader buffer = new BufferedReader(
                            new InputStreamReader(inputStream));
                    String s="";
                    while ((s=buffer.readLine())!=null){
                        stringBuffer.append(s);
                        System.out.println(s);
                    }

чтобы убедиться, что я успешно читаю xml, и оказывается, что код работает правильно. Далее я использую следующий код для анализа xml

XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
            XmlPullParser myparser = xmlFactoryObject.newPullParser();

            myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES
                    , false);
            myparser.setInput(inputStream, null);

            int event = myparser.getEventType();

            while (event != XmlPullParser.END_DOCUMENT){
                Log.d("XMLPullParserHandler", "sdfdsf " + myparser.getName());
                String name = myparser.getName();

Но я получаю java.lang.NullPointerException в myparser.getName(); также приведенный выше журнал показывает «sdfdsf null».

Что я делаю неправильно?


person Rohan Kandwal    schedule 18.08.2014    source источник
comment
вы хотите проанализировать xml или изменить режим на json. api.openweathermap.org/data/2.5/ разобрать json   -  person Raghunandan    schedule 18.08.2014
comment
@Raghunandan Я учусь анализировать XML, следующий JSON. Итак, я хотел бы разобрать в xml.   -  person Rohan Kandwal    schedule 18.08.2014


Ответы (2)


Вы можете либо проанализировать данный xml, либо изменить режим на json и проанализировать json.

Ваш тег xml выглядит так

<city id="2643743" name="London"> 
// tag name is city
// id and name are attributes with values 2643743 and London

Примечание. Я показал разбор только нескольких тегов. Но это должно помочь вам понять и сделать разбор всего остального самостоятельно.

Из документации

public abstract String getName () Добавлено в уровень API 1

Для событий START_TAG или END_TAG возвращается (локальное) имя текущего элемента, если включены пространства имен. Когда обработка пространства имен отключена, возвращается необработанное имя. Для событий ENTITY_REF возвращается имя сущности. Если текущее событие не является START_TAG, END_TAG или ENTITY_REF, возвращается null.

Чтобы разобрать xml и получить значения

public class XMLPullParserHandler {



    public XMLPullParserHandler() {

    }
    public Void parse(InputStream is) {
        XmlPullParserFactory factory = null;
        XmlPullParser parser = null;
        try {
            factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            parser = factory.newPullParser();

            parser.setInput(is, null);
            boolean check =false;

           //factory instantiates an object

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

                switch (eventType) {
                case XmlPullParser.START_TAG:

                    String tagname = parser.getName();
                    Log.i("Tag names are ",tagname);

                    if (tagname.equalsIgnoreCase("city")) {

                        if(parser.getAttributeValue(null, "id").equals("264374"))
                        {
                             String cityname= parser.getAttributeValue(null, "name");
                             Log.i(" City Name is ",cityname);
                        }

                    }
                    if (tagname.equalsIgnoreCase("coord")) {

                             String lat= parser.getAttributeValue(null, "lat");
                             String lon= parser.getAttributeValue(null, "lon");
                             Log.i("Latitude and Longitude is","Lat= "+lat+"Lon= "+lon);

                    }
                    if (tagname.equalsIgnoreCase("sun")) {

                     String rise= parser.getAttributeValue(null, "rise");
                     String set= parser.getAttributeValue(null, "set");
                     Log.i("Sun Rise and Sun set is","Rise= "+rise+"Set= "+set);

               }

                    break;

                case XmlPullParser.TEXT:
                    break;

                case XmlPullParser.END_TAG:


                    break;

                default:
                    break;
                }
                eventType = parser.next();
            }

        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

Журнал

08-18 16:14:35.885: I/City Name is(31634): London
08-18 16:14:35.885: I/Latitude and Longitude is(31634): Lat= 51.51Lon= -0.13
08-18 16:14:35.885: I/Sun Rise and Sun set is(31634): Rise= 2014-08-18T04:51:39Set= 2014-08-18T19:16:53

Также, если ваш тег xml выглядит так, как показано ниже

<cityname type="test">City is London</cityname> 

Чтобы получить значение

case XmlPullParser.TEXT:
       text = parser.getText();
break;

case XmlPullParser.END_TAG:
       if (tagname.equalsIgnoreCase("cityname")) {                             
        Log.i("Name is",text);
       }
break;

Редактировать:

Асинтаск

class TheTask extends AsyncTask<Void,Void,Void>
{

@Override
protected Void doInBackground(Void... params) {
    // TODO Auto-generated method stub
    String response;
       try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet("http://api.openweathermap.org/data/2.5/weather?q=London&mode=xml");

            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            response = EntityUtils.toString(httpEntity);

            InputStream is = new ByteArrayInputStream(response.getBytes(Charset.forName("UTF-8")));
            new XMLPullParserHandler().parse(is); 

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    return null;
}   
}
person Raghunandan    schedule 18.08.2014
comment
Спасибо за такое подробное описание, но в моем коммутаторе срабатывает только случай по умолчанию один раз (я скопировал ваш код), что означает, что что-то не так с моим входным потоком. Не могли бы вы поделиться своим HTTPURLConnection и кодом входного потока? - person Rohan Kandwal; 18.08.2014
comment
@RohanKandwal я взял xml, скопировал его в папку с ресурсами и проанализировал его оттуда. мне придется написать весь код для проверки, и это займет некоторое время - person Raghunandan; 18.08.2014
comment
@RohanKandwal проверьте правку. просто вызовите асинтаск там, где вам нужно - person Raghunandan; 18.08.2014
comment
@RohanKandwal, что теперь происходит?? - person Raghunandan; 18.08.2014
comment
@RohanKandwal рад, что это помогло - person Raghunandan; 18.08.2014

START_DOCUMENT — это первое событие, которое вы всегда получаете от парсера, а getName() возвращает не null только в случае событий START_TAG, END_TAG и ENTITY_REF.

Для событий START_TAG или END_TAG возвращается (локальное) имя текущего элемента, если включены пространства имен. Когда обработка пространства имен отключена, возвращается необработанное имя. Для событий ENTITY_REF возвращается имя сущности. Если текущее событие не является START_TAG, END_TAG или ENTITY_REF, возвращается null.

Попробуй это:

while (event != XmlPullParser.END_DOCUMENT) {
    if (event == XmlPullParser.START_TAG || event == XmlPullParser.END_TAG) {
        Log.d("XMLPullParserHandler", "sdfdsf " + myparser.getName());
        String name = myparser.getName();
    }
    event = myparser.next();
}
person Alexander Sukharev    schedule 18.08.2014