4

我正在做一个必须从 url 获取 XML 文件并解析它的应用程序。我总是找到这个日志猫(PS:我找不到正确的 google prettify sintax 代码突出显示):

11-06 23:12:44.940: E/Trace(8751): error opening trace file: No such file or directory(2)
11-06 23:12:51.345: E/Error:(8751): expected: /hr read: body (position:END_TAG </body>@6:8 in java.io.StringReader@431887b8) 
11-06 23:12:51.360: E/AndroidRuntime(8751): FATAL EXCEPTION: AsyncTask #1
11-06 23:12:51.360: E/AndroidRuntime(8751): java.lang.RuntimeException: An error occured while executing doInBackground()
11-06 23:12:51.360: E/AndroidRuntime(8751):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at java.lang.Thread.run(Thread.java:856)
11-06 23:12:51.360: E/AndroidRuntime(8751): Caused by: java.lang.NullPointerException
11-06 23:12:51.360: E/AndroidRuntime(8751):     at com.ambro.app.Update$connection.doInBackground(Update.java:39)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at com.ambro.app.Update$connection.doInBackground(Update.java:1)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-06 23:12:51.360: E/AndroidRuntime(8751):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-06 23:12:51.360: E/AndroidRuntime(8751):     ... 5 more

xml 可以在以下位置找到:http ://www.lookedpath.tk/apps/firstapp/version.xml

update.java 代码:

public class Update extends Activity {
    private TextView testo2;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.update);
        super.onCreate(savedInstanceState);
        testo2= (TextView) findViewById(R.id.textView2);

    }
    public void goToUpdate (View view) {
        System.out.println("ciao");
        new connection().execute();
    }
    public class connection extends AsyncTask<Void, Void, Boolean> {
        protected Boolean doInBackground(Void... params) {
             boolean updated=false;
             String lastversion=null;
             Element e=null;
             final String URL = "http://www.lookedpath.tk/apps/firstapp/version.xml";
             final String VERSION = "version";
             final String APPLICATION = "application";
             XMLParser parser = new XMLParser();
             String xml = parser.getXmlFromUrl(URL); // getting XML
             Document doc = parser.getDomElement(xml); // getting DOM element

             NodeList nl = doc.getElementsByTagName(APPLICATION);
             for (int i=0;i<nl.getLength();i++) {
                e = (Element) nl.item(0);
                lastversion = parser.getValue(e, VERSION); // name child value
             }

             String actver = getString(R.string.version);
             if(actver==lastversion) updated=true;

             return updated;
        }
        protected void onPostExecute(Boolean... result) {
            if(result[0]==false){
                testo2.setText(R.string.newversion);
            } else {
                testo2.setText(R.string.nonewversion);
            }

        }

    };

}

所以这是 xmlparser.java 文件:

public class XMLParser {
public String getXmlFromUrl(String url) {
    String xml = null;

    try {
        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        xml = EntityUtils.toString(httpEntity);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // return XML
    return xml;
}

public Document getDomElement(String xml){
    Document doc = null;
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {

        DocumentBuilder db = dbf.newDocumentBuilder();

        InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xml));
            doc = db.parse(is); 

        } catch (ParserConfigurationException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (SAXException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (IOException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        }
            // return DOM
        return doc;
}
public String getValue(Element item, String str) {
    NodeList n = item.getElementsByTagName(str);
    return this.getElementValue(n.item(0));
}

public final String getElementValue( Node elem ) {
         Node child;
         if( elem != null){
             if (elem.hasChildNodes()){
                 for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
                     if( child.getNodeType() == Node.TEXT_NODE  ){
                         return child.getNodeValue();
                     }
                 }
             }
         }
         return "";
  }
}

logcat 说错误在更新类的第 39 行:

NodeList nl = doc.getElementsByTagName(APPLICATION);

但我无法解决问题。谁能帮我?

更新: 我已经修复了错误 405,但我仍然有一个空指针异常。我发现程序运行正确,但由于此异常而从未进入后执行方法。

4

6 回答 6

3

我试过你的代码没有任何问题,很好。问题出在链接中。

在浏览器中看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<menu>
<application>
<version>1.5</version>
</application>
</menu>

但是当我打印 xml 变量时,它给了我

<html>
<head><title>405 Not Allowed</title></head>
<body bgcolor="white">
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx</center>
</body>
</html>

然后在 dom 变量中你得到 null 并且当你尝试在 nl 变量中找到为 null 的元素时你得到错误..,。

我用其他一些 xml 提要尝试了你的代码,效果很好..,。

于 2012-11-07T13:38:28.660 回答
0

从日志中,我可以看到 Update.java 第 39 行中有一个 NullPointer。您可以从那里开始。我相信它与 AsyncTask 无关。

于 2012-11-07T06:55:53.407 回答
0

您可以检查此链接以从 xml 解析 xml。 http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/

在您的活动中,您正在开发AsyncTask但您忘记了覆盖onPreExecute方法。请参阅此示例,了解如何AsyncTask在您的活动中进行开发。

package com.androidhive.jsonparsing;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
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.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class AndroidJSONParsingActivity extends ListActivity {

    // url to make request
    private static String url = "http://api.androidhive.info/contacts/";

    // JSON Node names
    private static final String TAG_CONTACTS = "contacts";
    private static final String TAG_ID = "id";
    private static final String TAG_NAME = "name";
    private static final String TAG_EMAIL = "email";
    private static final String TAG_ADDRESS = "address";
    private static final String TAG_GENDER = "gender";
    private static final String TAG_PHONE = "phone";
    private static final String TAG_PHONE_MOBILE = "mobile";
    private static final String TAG_PHONE_HOME = "home";
    private static final String TAG_PHONE_OFFICE = "office";
    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    // contacts JSONArray
    JSONArray contacts = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        new GetEventsTask().execute("");
    }

    protected class GetEventsTask extends
            AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> {
        protected ArrayList<HashMap<String, String>> contactList;

        private final ProgressDialog dialog = new ProgressDialog(
                AndroidJSONParsingActivity.this);

        //PreExecute Method

        protected void onPreExecute() {
            this.dialog.setMessage("Loading, Please Wait..");
            this.dialog.setCancelable(false);
            this.dialog.show();
        }

        //doInBackground Method

        @Override
        protected ArrayList<HashMap<String, String>> doInBackground(
                String... params) {
            contactList = new ArrayList<HashMap<String, String>>();
            // Making HTTP request
            try {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, "iso-8859-1"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                is.close();
                json = sb.toString();

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

            // try parse the string to a JSON object
            try {
                jObj = new JSONObject(json);
                Log.i("json objects",""+json);
            } catch (JSONException e) {
                Log.e("JSON Parser", "Error parsing data " + e.toString());
            }
            try {
                // Getting Array of Contacts
                contacts = jObj.getJSONArray(TAG_CONTACTS);

                // looping through All Contacts
                for (int i = 0; i < contacts.length(); i++) {
                    JSONObject c = contacts.getJSONObject(i);

                    // Storing each json item in variable
                    String id = c.getString(TAG_ID);
                    String name = c.getString(TAG_NAME);
                    String email = c.getString(TAG_EMAIL);
                    String address = c.getString(TAG_ADDRESS);
                    String gender = c.getString(TAG_GENDER);

                    // Phone number is agin JSON Object
                    JSONObject phone = c.getJSONObject(TAG_PHONE);
                    String mobile = phone.getString(TAG_PHONE_MOBILE);
                    String home = phone.getString(TAG_PHONE_HOME);
                    String office = phone.getString(TAG_PHONE_OFFICE);

                    // creating new HashMap
                    HashMap<String, String> map = new HashMap<String, String>();

                    // adding each child node to HashMap key => value
                    map.put(TAG_ID, id);
                    map.put(TAG_NAME, name);
                    map.put(TAG_EMAIL, email);
                    map.put(TAG_PHONE_MOBILE, mobile);

                    // adding HashList to ArrayList
                    contactList.add(map);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return contactList;
        }

        //onPostExecute Method 


        protected void onPostExecute(ArrayList<HashMap<String, String>> result) {

            ListAdapter adapter = new SimpleAdapter(getApplicationContext(),
                    contactList, R.layout.list_item, new String[] { TAG_NAME,
                            TAG_EMAIL, TAG_PHONE_MOBILE }, new int[] {
                            R.id.name, R.id.email, R.id.mobile });
            // selecting single ListView item
            ListView lv = getListView();
            lv.setAdapter(adapter);



            // Launching new screen on Selecting Single ListItem
            lv.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view,
                        int position, long id) {
                    // getting values from selected ListItem
                    String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
                    String cost = ((TextView) view.findViewById(R.id.email)).getText().toString();
                    String description = ((TextView) view.findViewById(R.id.mobile)).getText().toString();

                    // Starting new intent
                    Intent in = new Intent(getApplicationContext(),SingleMenuItemActivity.class);
                    in.putExtra(TAG_NAME, name);
                    in.putExtra(TAG_EMAIL, cost);
                    in.putExtra(TAG_PHONE_MOBILE, description);
                    startActivity(in);
                }
            });
            if (this.dialog.isShowing()) {
                this.dialog.dismiss();
            }
        }

    }

}
于 2012-11-07T06:44:08.790 回答
0

您必须将正确的 DTD 添加到您的 xml(文档类型定义)中,尝试一下,您会看到解析运行顺利。第 1 步:生成正确的 DTD 第 2 步:将其添加到您的 xml 文件并保存 第 3 步:上传您的 xml 文件,解析它并享受。

于 2013-09-18T22:29:30.587 回答
0

你在那个位置只得到空 xml 所以调试你的应用程序首先检查你得到的任何 xml 响应????

如果你得到 null xml 然后使用下面的代码来解析 xml

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
public class XMLHandler extends DefaultHandler {

String elementValue = null;
Boolean elementOn = false;
userdata d = userdata.getInstance();
public static XMLGettersSetters data = null;

public static XMLGettersSetters getXMLData() {
    return data;
}

public static void setXMLData(XMLGettersSetters data) {
    XMLHandler.data = data;
}

/**

 * This will be called when the tags of the XML starts.

 **/

@Override

public void startElement(String uri, String localName, String qName,

        Attributes attributes) throws SAXException {

    elementOn = true;

    if (localName.equals("application"))

    {
        data = new XMLGettersSetters();
    } 

}

/**

 * This will be called when the tags of the XML end.

 **/

@Override

public void endElement(String uri, String localName, String qName)

        throws SAXException {

    elementOn = false;

    /**

     * Sets the values after retrieving the values from the XML tags

     * */

    if (localName.equalsIgnoreCase("version")){

        System.out.println("ststus" + elementValue);

        d.setIsregi(elementValue);


    }

/**

 * This is called to get the tags value

 **/

@Override

public void characters(char[] ch, int start, int length)

        throws SAXException {

    if (elementOn) {

        elementValue = new String(ch, start, length);

        elementOn = false;

    }
}
}
于 2012-11-07T07:00:57.260 回答
0

嘿,看看我的图书馆

您可以使用它轻松操作 XML ;)

于 2012-11-06T23:29:37.240 回答