0

I'm trying to populate a database from an xml file. It work pretty well, but the problem is when I try to load the xml from a server. I've spent hours and hours, trying lots of different implementations but I always receive an exception. Here is my current code:

public void populateDB(){
    XmlPullParserFactory pullParserFactory;
    ArrayList<Product> products = null;

    try {
        pullParserFactory = XmlPullParserFactory.newInstance();
        XmlPullParser parser = pullParserFactory.newPullParser();

        InputStream in_s = fContext.getApplicationContext().getAssets().open("products.xml");

        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
        parser.setInput(in_s, null);

        products =  parseXML(parser);

        String text = "";

        for(Product product:products)
        {

            text += "barcode : " + product.getBarcode() + " name : " + product.getName() + "\n";
        }

    } catch (XmlPullParserException e) {

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

    clearTable("products");
    ContentValues values = new ContentValues();
    for(int i = 0; i < products.size(); i++){
        values.clear();
        values.put("barcode", products.get(i).getBarcode());
        values.put("name", products.get(i).getName());
        values.put("itemcode", products.get(i).getItemcode());
        values.put("description", products.get(i).getDescription());

        insertProduct(values);
    }
}

And this is parseXML(), where I parse the file and generate a list of products.

private ArrayList<Product> parseXML(XmlPullParser parser) throws XmlPullParserException,IOException
{
    ArrayList<Product> products = null;
    int eventType = parser.getEventType();
    Product product = null;

    while (eventType != XmlPullParser.END_DOCUMENT){
        String name;
        switch (eventType){
            case XmlPullParser.START_DOCUMENT:
                products = new ArrayList();
                break;
            case XmlPullParser.START_TAG:
                name = parser.getName();
                if (name.equals("product")){
                    product = new Product();
                } else if (product != null){
                    if (name.equals("barcode")){
                        product.setBarcode(parser.nextText());
                    } else if (name.equals("name")){
                        product.setName(parser.nextText());
                    } else if (name.equals("itemcode")){
                        product.setItemcode(Integer.parseInt(parser.nextText()));
                    } else if (name.equals("description")){
                        product.setDescription(parser.nextText());
                    }
                }
                break;
            case XmlPullParser.END_TAG:
                name = parser.getName();
                if (name.equalsIgnoreCase("product") && product != null){
                    products.add(product);
                }
        }
        eventType = parser.next();
    }

    return products;

}

Now this works only with local files, but if I want to load it from a url? I tried the solution given in this thread, and this, this, this and this, but still it doesn't work.

It seems that the instruction parser.setInput(in_s, null); does not accept an inputstream containing an url.

The xml file path is the following: http://cendav.altervista.org/gestione_magazzino/products.xml

7
  • So the underlying question is how to get an InputStream from a url? Commented Sep 15, 2017 at 7:50
  • Not properly, because I tried different ways to get the InputStream, reading lots of topics and it never worked. So I don't know if the problem is the InputStream, or the url, or something else. Commented Sep 15, 2017 at 7:54
  • your question is how to parse xml? Commented Sep 15, 2017 at 7:56
  • No I able to parse the xml but I cannot load it from url. Commented Sep 15, 2017 at 7:58
  • what? you can parse the xml but cannot load the url??? Commented Sep 15, 2017 at 7:59

1 Answer 1

1

Normally I'll put in an asyncTask:

class getXMLResponseAsyncTask extends AsyncTask<String, Void, Boolean>{

        @Override
        protected void onPreExecute(){
         //do something
        }


        @Override
        public Boolean doInBackground(String... urls) {
            URL url;

            try {
                url = new URL(urls[0]);

                URLConnection connection = url.openConnection();

                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse(connection.getInputStream());


                NodeList nodes = doc.getElementsByTagName("products");
                for (int i = 0; i < nodes.getLength(); i++) {
                    Element element = (Element) nodes.item(i);
                    NodeList barcode = element.getElementsByTagName("barcode");
                    NodeList name = element.getElementsByTagName("name");
                    NodeList itemcode = element.getElementsByTagName("itemcode");



                    Element barcodeval = (Element) barcode.item(0);
                    Element nameval = (Element) name.item(0);
                    Element itemcodeval = (Element) itemcode.item(0);



                    String BARCODE = barcodeval.getTextContent();
                    String NAME  = nameval.getTextContent();
                    String ITEMCODE = itemcodeval.getTextContent();


                }


            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            }

            return false;
        }

        public void onPostExecute(Boolean result) {
        //do something
        }
    }

AND FINALLY YOU CAN USE IT ANYTIME YOU WANT

    new getXMLResponseAsyncTask().execute("http://cendav.altervista.org/gestione_magazzino/products.xml");
Sign up to request clarification or add additional context in comments.

6 Comments

This line DocumentsContract.Document doc = builder.parse((connection.getInputStream())); gives me the error of incopatible types.
did you import import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; ?
DocumentsContract.Document doc = builder.parse((connection.getInputStream())); Incopatible types: Required: android.provider.DocumentsConrtact.Document Found: org.w3c.dom.Document
import these: import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException;
and make sure this line Document doc = builder.parse(connection.getInputStream()); is is using it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.