XMLPullParser返回空白结果

时间:2015-03-02 19:31:37

标签: java android xml

我正在尝试提取和解析我正在摆弄的XML文件。我试图将其拉下来并在列表视图中显示它。

我无法弄清楚为什么它没有返回结果?

请参阅以下活动:

  

MainActivity.java

package com.ryan.bobxmlpullproject;

import java.io.FileNotFoundException;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class MainActivity extends Activity {


    private SitesAdapter mAdapter;
    private ListView sitesList;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i("StackSites", "OnCreate()");
        setContentView(R.layout.activity_main);



        //Get reference to our ListView
        sitesList = (ListView)findViewById(R.id.sitesList);

        //Set the click listener to launch the browser when a row is clicked.
        sitesList.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View v, int pos,long id) {
                String url = mAdapter.getItem(pos).getLink();
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(url));
                startActivity(i);

            }

        });

        /*
         * If network is available download the xml from the Internet.
         * If not then try to use the local file from last time.
         */
        if(isNetworkAvailable()){
            Log.i("StackSites", "starting download Task");
            SitesDownloadTask download = new SitesDownloadTask();
            download.execute();
        }else{
            mAdapter = new SitesAdapter(getApplicationContext(), -1, SitesXmlPullParser.getStackSitesFromFile(MainActivity.this));
            sitesList.setAdapter(mAdapter);
        }

    }

    //Helper method to determine if Internet connection is available.
    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }



    /*
     * AsyncTask that will download the xml file for us and store it locally.
     * After the download is done we'll parse the local file.
     */
    private class SitesDownloadTask extends AsyncTask<Void, Void, Void>{

        @Override
        protected Void doInBackground(Void... arg0) {
            //Download the file
            try {
                Downloader.DownloadFromUrl("https://www.dropbox.com/s/w463wkx85dlbtbx/iPhoneSearch.xml", openFileOutput("StackSites.xml", Context.MODE_PRIVATE));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result){
            //setup our Adapter and set it to the ListView.
            mAdapter = new SitesAdapter(MainActivity.this, -1, SitesXmlPullParser.getStackSitesFromFile(MainActivity.this));
            sitesList.setAdapter(mAdapter);
            Log.i("StackSites", "adapter size = "+ mAdapter.getCount());
        }
    }

}
  

row_site.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp" >

    <ProgressBar
        android:id="@+id/progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/iconImg"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_marginRight="8dp" />

    <TextView
        android:id="@+id/nameTxt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/iconImg"
        android:textSize="16sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/aboutTxt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/iconImg"
        android:textSize="12sp"
        android:layout_below="@id/nameTxt"
        />
    <TextView
        android:id="@+id/titleTxt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/iconImg"
        android:textSize="12sp"
        android:layout_below="@id/nameTxt"
        />

</RelativeLayout>
  

SitesXmlPullParser.Java

package com.ryan.bobxmlpullproject;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.content.Context;

public class SitesXmlPullParser {

    static final String KEY_SITE = "tradeSummary";
    static final String KEY_NAME = "userAlias";
    //static final String KEY_LINK = "link";
    static final String KEY_ABOUT = "title";
    static final String KEY_IMAGE_URL = "thumbnailImageURL";

    public static List<StackSite> getStackSitesFromFile(Context ctx) {

        // List of StackSites that we will return
        List<StackSite> stackSites;
        stackSites = new ArrayList<StackSite>();

        // temp holder for current StackSite while parsing
        StackSite curStackSite = null;
        // temp holder for current text value while parsing
        String curText = "";

        try {
            // Get our factory and PullParser
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser xpp = factory.newPullParser();

            // Open up InputStream and Reader of our file.
            FileInputStream fis = ctx.openFileInput("StackSites.xml");
            BufferedReader reader = new BufferedReader(new InputStreamReader(fis));

            // point the parser to our file.
            xpp.setInput(reader);

            // get initial eventType
            int eventType = xpp.getEventType();

            // Loop through pull events until we reach END_DOCUMENT
            while (eventType != XmlPullParser.END_DOCUMENT) {
                // Get the current tag
                String tagname = xpp.getName();

                // React to different event types appropriately
                switch (eventType) {
                    case XmlPullParser.START_TAG:
                        if (tagname.equalsIgnoreCase(KEY_SITE)) {
                            // If we are starting a new <site> block we need
                            //a new StackSite object to represent it
                            curStackSite = new StackSite();
                        }
                        break;

                    case XmlPullParser.TEXT:
                        //grab the current text so we can use it in END_TAG event
                        curText = xpp.getText();
                        break;

                    case XmlPullParser.END_TAG:
                        if (tagname.equalsIgnoreCase(KEY_SITE)) {
                            // if </site> then we are done with current Site
                            // add it to the list.
                            stackSites.add(curStackSite);
                        } else if (tagname.equalsIgnoreCase(KEY_NAME)) {
                            // if </name> use setName() on curSite
                            curStackSite.setName(curText);
                        } //else if (tagname.equalsIgnoreCase(KEY_LINK)) {
                            // if </link> use setLink() on curSite
                            //curStackSite.setLink(curText);
                //        }
                else if (tagname.equalsIgnoreCase(KEY_ABOUT)) {
                            // if </about> use setAbout() on curSite
                            curStackSite.setAbout(curText);
                        } else if (tagname.equalsIgnoreCase(KEY_IMAGE_URL)) {
                            // if </image> use setImgUrl() on curSite
                            curStackSite.setImgUrl(curText);
                        }
                        break;

                    default:
                        break;
                }
                //move on to next iteration
                eventType = xpp.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // return the populated list.
        return stackSites;
    }
}
  

SitesAdapter.java

package com.ryan.bobxmlpullproject;


        import java.util.List;

        import android.content.Context;
        import android.graphics.Bitmap;
        import android.util.Log;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        import android.widget.ArrayAdapter;
        import android.widget.ImageView;
        import android.widget.ProgressBar;
        import android.widget.RelativeLayout;
        import android.widget.TextView;

        import com.nostra13.universalimageloader.core.DisplayImageOptions;
        import com.nostra13.universalimageloader.core.ImageLoader;
        import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
        import com.nostra13.universalimageloader.core.assist.FailReason;
        import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;


/*
 * Custom Adapter class that is responsible for holding the list of sites after they
 * get parsed out of XML and building row views to display them on the screen.
 */
public class SitesAdapter extends ArrayAdapter<StackSite> {

    ImageLoader imageLoader;
    DisplayImageOptions options;


    public SitesAdapter(Context ctx, int textViewResourceId, List<StackSite> sites) {
        super(ctx, textViewResourceId, sites);

        //Setup the ImageLoader, we'll use this to display our images
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(ctx).build();
        imageLoader = ImageLoader.getInstance();
        imageLoader.init(config);

        //Setup options for ImageLoader so it will handle caching for us.
        options = new DisplayImageOptions.Builder()
                .cacheInMemory()
                .cacheOnDisc()
                .build();


    }


    /*
     * (non-Javadoc)
     * @see android.widget.ArrayAdapter#getView(int, android.view.View, android.view.ViewGroup)
     *
     * This method is responsible for creating row views out of a StackSite object that can be put
     * into our ListView
     */
    @Override
    public View getView(int pos, View convertView, ViewGroup parent){
        RelativeLayout row = (RelativeLayout)convertView;
        Log.i("StackSites", "getView pos = " + pos);
        if(null == row){
            //No recycled View, we have to inflate one.
            LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = (RelativeLayout)inflater.inflate(R.layout.row_site, null);
        }

        //Get our View References
        final ImageView iconImg = (ImageView)row.findViewById(R.id.iconImg);
        TextView nameTxt = (TextView)row.findViewById(R.id.nameTxt);
        TextView titleTxt = (TextView)row.findViewById(R.id.titleTxt);
        TextView aboutTxt = (TextView)row.findViewById(R.id.aboutTxt);
        final ProgressBar indicator = (ProgressBar)row.findViewById(R.id.progress);

        //Initially we want the progress indicator visible, and the image invisible
        indicator.setVisibility(View.VISIBLE);
        iconImg.setVisibility(View.INVISIBLE);

        //Setup a listener we can use to swtich from the loading indicator to the Image once it's ready
        ImageLoadingListener listener = new ImageLoadingListener(){



            @Override
            public void onLoadingStarted(String arg0, View arg1) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onLoadingCancelled(String arg0, View arg1) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) {
                indicator.setVisibility(View.INVISIBLE);
                iconImg.setVisibility(View.VISIBLE);
            }

            @Override
            public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
                // TODO Auto-generated method stub

            }

        };

        //Load the image and use our options so caching is handled.
        imageLoader.displayImage(getItem(pos).getImgUrl(), iconImg,options, listener);

        //Set the relavent text in our TextViews
        nameTxt.setText(getItem(pos).getName());
        aboutTxt.setText(getItem(pos).getAbout());
        titleTxt.setText(getItem(pos).getAbout());



        return row;


    }

}
  

Downloader.java

package com.ryan.bobxmlpullproject;


        import java.io.BufferedInputStream;
        import java.io.BufferedOutputStream;
        import java.io.FileOutputStream;
        import java.io.IOException;
        import java.io.InputStream;
        import java.net.URL;
        import java.net.URLConnection;

        import android.util.Log;

/*
 * Helper class for downloading a file.
 */
public class Downloader {

    //Tag for Log statements
    private static String myTag = "StackSites";

    //Handler msg that represents we are posting a progress update.
    static final int POST_PROGRESS = 1;

    /************************************************
     * Download a file from the Internet and store it locally
     *
     * @param URL - the url of the file to download
     * @param fos - a FileOutputStream to save the downloaded file to.
     ************************************************/
    public static void DownloadFromUrl(String URL, FileOutputStream fos) {  //this is the downloader method
        try {

            URL url = new URL(URL); //URL of the file

            //keep the start time so we can display how long it took to the Log.
            long startTime = System.currentTimeMillis();
            Log.d(myTag, "download begining");

            /* Open a connection to that URL. */
            URLConnection ucon = url.openConnection();

            // this will be useful so that you can show a tipical 0-100% progress bar
            //int lenghtOfFile = ucon.getContentLength();

            Log.i(myTag, "Opened Connection");

            /************************************************
             * Define InputStreams to read from the URLConnection.
             ************************************************/
            InputStream is = ucon.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            Log.i(myTag, "Got InputStream and BufferedInputStream");

            /************************************************
             * Define OutputStreams to write to our file.
             ************************************************/

            BufferedOutputStream bos = new BufferedOutputStream(fos);
            Log.i(myTag, "Got FileOutputStream and BufferedOutputStream");

            /************************************************
             * Start reading the and writing our file.
             ************************************************/
            byte data[] = new byte[1024];
            //long total = 0;
            int count;
            //loop and read the current chunk
            while ((count = bis.read(data)) != -1) {
                //keep track of size for progress.
                //total += count;

                //write this chunk
                bos.write(data, 0, count);
            }
            //Have to call flush or the  file can get corrupted.
            bos.flush();
            bos.close();

            Log.d(myTag, "download ready in "
                    + ((System.currentTimeMillis() - startTime))
                    + " milisec");
        } catch (IOException e) {
            Log.d(myTag, "Error: " + e);
        }
    }
}
  

StackSite.java

package com.ryan.bobxmlpullproject;


/*
 * Data object that holds all of our information about a StackExchange Site.
 */
public class StackSite {

    private String name;
    private String link;
    private String about;
    private String imgUrl;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getLink() {
        return link;
    }
    public void setLink(String link) {
        this.link = link;
    }
    public String getAbout() {
        return about;
    }
    public void setAbout(String about) {
        this.about = about;
    }
    public String getImgUrl() {
        return imgUrl;
    }
    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }
    @Override
    public String toString() {
        return "StackSite [name=" + name + ", link=" + link + ", about="
                + about + ", imgUrl=" + imgUrl + "]";
    }
}

请帮忙,这是我在应用程序中遇到的最后一个问题,并希望能够让它正常工作

可以在此处找到XML文件:https://www.dropbox.com/s/w463wkx85dlbtbx/iPhoneSearch.xml

  

日志:

03-02 21:02:51.280    1532-1532/com.ryan.bobxmlpullproject I/StackSites﹕ OnCreate()
03-02 21:02:51.316    1532-1532/com.ryan.bobxmlpullproject I/StackSites﹕ starting download Task
03-02 21:02:51.322    1532-1551/com.ryan.bobxmlpullproject D/StackSites﹕ download begining
03-02 21:02:51.332    1532-1552/com.ryan.bobxmlpullproject D/OpenGLRenderer﹕ Render dirty regions requested: true
03-02 21:02:51.334    1532-1551/com.ryan.bobxmlpullproject I/StackSites﹕ Opened Connection
03-02 21:02:51.356    1532-1532/com.ryan.bobxmlpullproject D/﹕ HostConnection::get() New Host Connection established 0xacf3cf30, tid 1532
03-02 21:02:51.394    1532-1532/com.ryan.bobxmlpullproject D/Atlas﹕ Validating map...
03-02 21:02:51.442    1532-1552/com.ryan.bobxmlpullproject D/libEGL﹕ loaded /system/lib/egl/libEGL_emulation.so
03-02 21:02:51.443    1532-1552/com.ryan.bobxmlpullproject D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_emulation.so
03-02 21:02:51.459    1532-1552/com.ryan.bobxmlpullproject D/libEGL﹕ loaded /system/lib/egl/libGLESv2_emulation.so
03-02 21:02:51.475    1532-1552/com.ryan.bobxmlpullproject D/﹕ HostConnection::get() New Host Connection established 0xa4816120, tid 1552
03-02 21:02:51.493    1532-1552/com.ryan.bobxmlpullproject I/OpenGLRenderer﹕ Initialized EGL, version 1.4
03-02 21:02:51.618    1532-1552/com.ryan.bobxmlpullproject D/OpenGLRenderer﹕ Enabling debug mode 0
03-02 21:02:51.651    1532-1552/com.ryan.bobxmlpullproject W/EGL_emulation﹕ eglSurfaceAttrib not implemented
03-02 21:02:51.652    1532-1552/com.ryan.bobxmlpullproject W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa48192a0, error=EGL_SUCCESS
03-02 21:02:54.308    1532-1551/com.ryan.bobxmlpullproject I/StackSites﹕ Got InputStream and BufferedInputStream
03-02 21:02:54.308    1532-1551/com.ryan.bobxmlpullproject I/StackSites﹕ Got FileOutputStream and BufferedOutputStream
03-02 21:02:54.317    1532-1551/com.ryan.bobxmlpullproject D/StackSites﹕ download ready in 2996 milisec
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ org.xmlpull.v1.XmlPullParserException: unterminated entity ref (position:TEXT @32:51 in java.io.BufferedReader@f91f5f1)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at org.kxml2.io.KXmlParser.readEntity(KXmlParser.java:1219)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at org.kxml2.io.KXmlParser.readValue(KXmlParser.java:1401)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at org.kxml2.io.KXmlParser.next(KXmlParser.java:393)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at org.kxml2.io.KXmlParser.next(KXmlParser.java:313)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.ryan.bobxmlpullproject.SitesXmlPullParser.getStackSitesFromFile(SitesXmlPullParser.java:94)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.ryan.bobxmlpullproject.MainActivity$SitesDownloadTask.onPostExecute(MainActivity.java:97)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.ryan.bobxmlpullproject.MainActivity$SitesDownloadTask.onPostExecute(MainActivity.java:80)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.AsyncTask.finish(AsyncTask.java:632)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.AsyncTask.access$600(AsyncTask.java:177)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.Looper.loop(Looper.java:135)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5221)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:372)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
03-02 21:02:54.318    1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
03-02 21:02:54.325    1532-1532/com.ryan.bobxmlpullproject W/ImageLoader﹕ Unable to create external cache directory
03-02 21:02:54.332    1532-1532/com.ryan.bobxmlpullproject I/StackSites﹕ adapter size = 0

1 个答案:

答案 0 :(得分:0)

你的xml很糟糕。结束标记是&lt; / Root&gt;
它应该是&lt; / root&gt;