0

我在解析内部存储中的 xml 文件时遇到问题。我有一个看起来像这样的 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<entries>
    <entry>
        <name>Name 1</name>
        <submenu>Submenu 1</submenu>
        <color>Color 1</color>
    </entry>
    <entry>
        <name>Name 2</name>
        <submenu>Submenu 2</submenu>
        <color>Color 2</color>
    </entry>
    <entry>
        <name>Name 3</name>
        <submenu>Submenu 3</submenu>
        <color>Color 3</color>
    </entry>
</entries>

我的资产文件夹中有一个名为 test.xml 的 xml 文件副本,我的网络服务器上有一个名为 test.xml 的副本。当我尝试解析资产文件夹中的文件时,一切正常。当我从互联网下载文件并尝试从内部存储解析它时,它不起作用。这是我的活动代码,其中包含所有功能:

package com.example.testdl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

ProgressDialog mProgressDialog;
Button button;
int x = 0;

String URL = "http://www.classicknightstudio.com/marthasvillans/test.xml";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setTitle("Test1");
    setContentView(R.layout.activity_main);

    button = (Button) findViewById(R.id.myButton);
    button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {

            if (x == 0) {

                // Execute DownloadFile AsyncTask
                new DownloadFile().execute(URL);
                x = x + 1;

            } else {

                logNames();

            }
        }

    });

}

// DownloadFile AsyncTask
private class DownloadFile extends AsyncTask<String, Integer, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setTitle("Downloads");
        mProgressDialog.setMessage("Downloading, Please Wait!");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.show();
    }

    @Override
    protected String doInBackground(String... sUrl) {
        try {
            URL url = new URL(sUrl[0]);
            URLConnection connection = url.openConnection();
            connection.connect();

            // Detect the file length
            int fileLength = connection.getContentLength();

            // Download the file
            InputStream input = new     BufferedInputStream(url.openStream());

            FileOutputStream output = openFileOutput("test.xml",
                    Context.MODE_PRIVATE);
            output.write("test.xml".getBytes());

            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                // Publish the progress
                publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }

            // Close connection
            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {
            // Error Log
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);

        mProgressDialog.setProgress(progress[0]);
    }
}


private class XmlParser {

    private final String ns = null;

    public List parse(InputStream in) throws XmlPullParserException,
            IOException {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,
                    false);
            parser.setInput(in, null);
            parser.nextTag();
            return readFeed(parser);
        } finally {
            in.close();
        }
    }

    private List<Entry> readFeed(XmlPullParser parser)
            throws XmlPullParserException, IOException {
        List<Entry> entries = new ArrayList<Entry>();

        parser.require(XmlPullParser.START_TAG, ns, "entries");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();

            if (name.equals("entry")) {
                entries.add(readEntry(parser));
            } else {
                skip(parser);
            }
        }
        return entries;
    }

    private Entry readEntry(XmlPullParser parser)
            throws XmlPullParserException, IOException {
        parser.require(XmlPullParser.START_TAG, ns, "entry");
        String titleName = null;
        String submenu = null;
        String color = null;
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String name = parser.getName();
            if (name.equals("name")) {
                titleName = readTitleName(parser);
            } else if (name.equals("submenu")) {
                submenu = readSubmenu(parser);
            } else if (name.equals("color")) {
                color = readColor(parser);
            } else {
                skip(parser);
            }
        }
        return new Entry(titleName, submenu, color);
    }

    private String readTitleName(XmlPullParser parser) throws IOException,
            XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "name");
        String titleName = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "name");
        return titleName;
    }

    private String readSubmenu(XmlPullParser parser) throws IOException,
            XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "submenu");
        String submenu = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "submenu");
        return submenu;
    }

    private String readColor(XmlPullParser parser) throws IOException,
            XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, ns, "color");
        String color = readText(parser);
        parser.require(XmlPullParser.END_TAG, ns, "color");
        return color;
    }

    private String readText(XmlPullParser parser) throws IOException,
            XmlPullParserException {
        String result = "";
        if (parser.next() == XmlPullParser.TEXT) {
            result = parser.getText();
            parser.nextTag();
        }
        return result;
    }

    private void skip(XmlPullParser parser) throws XmlPullParserException,
            IOException {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            throw new IllegalStateException();
        }
        int depth = 1;
        while (depth != 0) {
            switch (parser.next()) {
            case XmlPullParser.END_TAG:
                depth--;
                break;
            case XmlPullParser.START_TAG:
                depth++;
                break;
            }
        }
    }

}

public static class Entry {
    public final String titleName;
    public final String submenu;
    public final String color;

    public Entry(String titleName, String submenu, String color) {
        this.titleName = titleName;
        this.submenu = submenu;
        this.color = color;
    }

    public String getTitleName() {
        return titleName;
    }

    public String getSubmenu() {
        return submenu;
    }

    public String getColor() {
        return color;
    }
}

protected void logNames() {

    File file = getBaseContext().getFileStreamPath("test.xml");

    if (file.exists()) {

        Log.d("TEST1", "file exists");

        try {

            // InputStream in = getApplicationContext().getAssets().open("test.xml");

            FileInputStream in = openFileInput("test.xml");

            XmlParser myParse = new XmlParser();

            try {

                @SuppressWarnings("unchecked")
                ArrayList<Entry> TheParse = (ArrayList<Entry>) myParse
                        .parse(in);

                for (int i = 0; i < TheParse.size(); i = i + 1) {
                    Log.d("TEST1", "" + TheParse.get(i).getTitleName());
                }

            } catch (XmlPullParserException e) {

                e.printStackTrace();
            }

        } catch (IOException e) {

            e.printStackTrace();
        }

    }

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

}

活动设置为当您第一次按下按钮时,它会从网络下载文件。然后,当您第二次按下该按钮时,它会在 logcat 中记录每个条目的名称。

在 logNames 方法中,我发布的代码使用 FileInputStream in = openFileInput("test.xml");

上面注释掉的是一个从 assets 文件夹中获取文件的流。我知道要从资产文件夹中读取文件,我不需要所有下载的东西。所以,如果我注释掉:

FileInputStream in = openFileInput("test.xml");

在 logNames 方法中并取消注释:

InputStream in = getApplicationContext().getAssets().open("test.xml");

然后一切正常,名称显示在日志猫中。但是,如果我使用如图所示的代码(尝试从网络下载 xml,将其保存到外部存储,然后解析它),我会收到以下错误:

08-12 04:38:56.899: W/System.err(17622): org.xmlpull.v1.XmlPullParserException:    Unexpected token (position:TEXT test.xml@1:9 in java.io.InputStreamReader@4278f850) 
08-12 04:38:56.909: W/System.err(17622):    at      org.kxml2.io.KXmlParser.next(KXmlParser.java:426)
08-12 04:38:56.909: W/System.err(17622):    at org.kxml2.io.KXmlParser.next(KXmlParser.java:310)
08-12 04:38:56.909: W/System.err(17622):    at org.kxml2.io.KXmlParser.nextTag(KXmlParser.java:2029)
08-12 04:38:56.909: W/System.err(17622):    at com.example.testdl.MainActivity$XmlParser.parse(MainActivity.java:143)
08-12 04:38:56.909: W/System.err(17622):    at com.example.testdl.MainActivity.logNames(MainActivity.java:292)
08-12 04:38:56.909: W/System.err(17622):    at com.example.testdl.MainActivity$1.onClick(MainActivity.java:59)
08-12 04:38:56.909: W/System.err(17622):    at android.view.View.performClick(View.java:4203)
08-12 04:38:56.909: W/System.err(17622):    at android.view.View$PerformClick.run(View.java:17189)
08-12 04:38:56.909: W/System.err(17622):    at android.os.Handler.handleCallback(Handler.java:615)
08-12 04:38:56.909: W/System.err(17622):    at android.os.Handler.dispatchMessage(Handler.java:92)
08-12 04:38:56.909: W/System.err(17622):    at android.os.Looper.loop(Looper.java:137)
08-12 04:38:56.909: W/System.err(17622):    at android.app.ActivityThread.main(ActivityThread.java:4950)
08-12 04:38:56.909: W/System.err(17622):    at java.lang.reflect.Method.invokeNative(Native Method)
08-12 04:38:56.909: W/System.err(17622):    at java.lang.reflect.Method.invoke(Method.java:511)
08-12 04:38:56.909: W/System.err(17622):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
08-12 04:38:56.909: W/System.err(17622):    at c     com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
08-12 04:38:56.919: W/System.err(17622):    at dalvik.system.NativeStart.main(Native    Method)
08-12 04:38:58.210: D/TEST1(17622): file exists
08-12 04:38:58.210: W/System.err(17622): org.xmlpull.v1.XmlPullParserException:    Unexpected token (position:TEXT test.xml@1:9 in java.io.InputStreamReader@4279b7c8) 
08-12 04:38:58.210: W/System.err(17622):    at org.kxml2.io.KXmlParser.next(KXmlParser.java:426)
08-12 04:38:58.210: W/System.err(17622):    at org.kxml2.io.KXmlParser.next(KXmlParser.java:310)
08-12 04:38:58.210: W/System.err(17622):    at org.kxml2.io.KXmlParser.nextTag(KXmlParser.java:2029)
08-12 04:38:58.210: W/System.err(17622):    at com.example.testdl.MainActivity$XmlParser.parse(MainActivity.java:143)
08-12 04:38:58.220: W/System.err(17622):    at com.example.testdl.MainActivity.logNames(MainActivity.java:292)
08-12 04:38:58.220: W/System.err(17622):    at com.example.testdl.MainActivity$1.onClick(MainActivity.java:59)
08-12 04:38:58.220: W/System.err(17622):    at android.view.View.performClick(View.java:4203)
08-12 04:38:58.220: W/System.err(17622):    at and android.view.View$PerformClick.run(View.java:17189)
08-12 04:38:58.220: W/System.err(17622):    at android.os.Handler.handleCallback(Handler.java:615)
08-12 04:38:58.220: W/System.err(17622):    at android.os.Handler.dispatchMessage(Handler.java:92)
08-12 04:38:58.220: W/System.err(17622):    at android.os.Looper.loop(Looper.java:137)
08-12 04:38:58.220: W/System.err(17622):    at android.app.ActivityThread.main(ActivityThread.java:4950)
08-12 04:38:58.220: W/System.err(17622):    at java.lang.reflect.Method.invokeNative(Native Method)
08-12 04:38:58.220: W/System.err(17622):    at java.lang.reflect.Method.invoke(Method.java:511)
08-12 04:38:58.220: W/System.err(17622):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
08-12 04:38:58.220: W/System.err(17622):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
08-12 04:38:58.220: W/System.err(17622):    at dalvik.system.NativeStart.main(Native Method)

该文件是否存在于 logNames 方法中的检查通过了,看起来该文件确实保存到了内部存储中。任何帮助表示赞赏。

4

2 回答 2

1

解决了。我的下载器类一定有问题。重写后,我让它工作了,......也适用于多个文件!这是新的下载器:

  private class GetXMLTask extends AsyncTask<String, Integer, Boolean> {

    private static final int DOWNLOAD_BUFFER_SIZE = 4096;
    int dlCount = 1;

    private Context context;

    int noOfURLs;

    public GetXMLTask(Context context) {
        this.context = context;
    }

    @Override
    protected Boolean doInBackground(String... urls) {
        noOfURLs = urls.length;


        for (String url : urls) {
            downloadFile(url);

        }

        return true;
    }

    private Boolean downloadFile(String urlString) {


        int count = 0;
        String basePath = "http://www.mysite.com/myFolder/";

        URL url;
        InputStream inputStream = null;
        BufferedOutputStream outputStream = null;

        File outFile;
        FileOutputStream fileStream;

        try {
            url = new URL(basePath + urlString);
            URLConnection connection = url.openConnection();
            int lenghtOfFile = connection.getContentLength();

            inputStream = new BufferedInputStream(url.openStream());


            outFile = new File(context.getFilesDir() + "/" + urlString);
            fileStream = new FileOutputStream(outFile);

            outputStream = new BufferedOutputStream(fileStream, DOWNLOAD_BUFFER_SIZE);

            byte data[] = new byte[1024];
            long total = 0;

            while ((count = inputStream.read(data)) != -1) {
                total += count;
                /*publishing progress update on UI thread.
                Invokes onProgressUpdate()*/
                publishProgress((int)((total*100)/lenghtOfFile));

                // writing data to byte array stream
                outputStream.write(data, 0, count);
            }
            outputStream.flush();



        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            FileUtils.close(inputStream);
            FileUtils.close(outputStream);
        }
        dlCount++;
        return true;
    }

    protected void onProgressUpdate(Integer... progress) {
        progressDialog.setProgress(progress[0]);

            progressDialog.setMessage("Downloading File " + dlCount + "/" + noOfURLs);

   }

   @Override
protected void onPostExecute(Boolean result) {

    super.onPostExecute(result);

    logNames();
    progressDialog.dismiss();
}   

}

要在活动中调用它,我使用:

/*Creating and executing background task*/
    GetXMLTask task = new GetXMLTask(getApplicationContext());
    task.execute(new String[] { URL3 });

    progressDialog = new ProgressDialog(this);
    progressDialog.setTitle(PROTOCOL_NAME);
    progressDialog.setMessage("Loading...");
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.setIndeterminate(false);
    progressDialog.setMax(100);
    progressDialog.setCancelable(true);
    progressDialog.show();

URL3 是我设置的字符串。您可以在该数组中添加任何您想要的字符串。logNames() 是下载完成后调用的方法。那里可能有任何方法。希望这可以帮助某人:)

于 2013-08-13T09:36:08.447 回答
0
  1. 如果你已经InputStream在这条线上InputStream input = new BufferedInputStream(url.openStream()); 那你为什么要转入文件并从文件中取回InputStream
  2. 您的文件路径错误,应该是这样的完整路径。FileInputStream in = openFileInput("/mnt/sdcard/../test.xml");
  3. 检查您的文件是否成功写入?

解决方案:

  1. 无需保存文件,可直接InputStream用于解析。
  2. 更正你的文件路径..
于 2013-08-12T10:05:21.033 回答