javaandroidxmlsaxparsersaxparseexception

SAXParseException: Unexpected token when trying to parse remote XML on Android


I am trying to parse an XML from the internet and display some of its data in a simple TextView. Here is my code:

    public class MainActivity extends AppCompatActivity {

    TextView tv1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv1=(TextView)findViewById(R.id.textView1);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        try {

            String UTF8 = "utf-8";
            URL url = new URL("http://pollenapps.com/AllergyAlertWebSVC/api/1.0/Forecast/ForecastForZipCode?Zipcode=02145&Affiliateid=9642&AppID=2.1.0&uid=6693636764.xml");
            URLConnection urlConnection = url.openConnection();
            //InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            //BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8));
            //InputStream in = new URL("http://pollenapps.com/AllergyAlertWebSVC/api/1.0/Forecast/ForecastForZipCode?Zipcode=02145&Affiliateid=9642&AppID=2.1.0&uid=6693636764.xml").openStream();
            //getAssets().open("file.xml");
            InputStream in = url.openStream();

            //InputStream is2 = new FileInputStream(file);

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            //Document doc = dBuilder.parse(new InputSource(new InputStreamReader(in, "UTF-8")));
            Document doc = dBuilder.parse(in, "UTF-8");
            //Document doc = dBuilder.parse(in);

            Element element = doc.getDocumentElement();
            element.normalize();

            NodeList nList = doc.getElementsByTagName("allergyForecast");

            for (int i=0; i<nList.getLength(); i++) {

                Node node = nList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element2 = (Element) node;
                    tv1.setText(getValue("Day0", element2));
                }
            }

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

    }

    private static String getValue(String tag, Element element) {
        NodeList nodeList = element.getElementsByTagName(tag).item(0).getChildNodes();
        Node node = nodeList.item(0);
        return node.getNodeValue();
    }
}

This code works as intended when I run it on a local file (one of those commended out InputStreams is for a local file) but when I try to run it on the XML file from the internet, I get the following error:

07-04 12:58:06.550 23289-23289/mystikos.pollentest W/System.err: org.xml.sax.SAXParseException: Unexpected token (position:TEXT {"allergyForecas...@1:990 in java.io.InputStreamReader@2ff0997)

Based on some research it seems like the parser can't tell what type of encoding the XML file has, so I need to define it. However, I am not sure how to define it here... my attempts at defining "UTF-8" encoding are visible in commented out lines, but those did not work. Any suggestions?

XML: http://pollenapps.com/AllergyAlertWebSVC/api/1.0/Forecast/ForecastForZipCode?Zipcode=02145&Affiliateid=9642&AppID=2.1.0&uid=6693636764.xml

Thank you!


Solution

  • Data that You get in response is in json, not in xml. Prefix .xml in your url is not take data in xml when you get inputStream from UrlOpenConnection, and can be removed. To see the data that you got:

            String data = "";
            while (in.available() > 0)
                data += (char)in.read();
            System.out.println(data);
    

    Result is : {"allergyForecast":{"Day0":4.1,"Day1":3.7,"Day2":4.6,"Day3":1.4,"Day4":2.9," ... }

    To parse date you can use Gson for example. Code snippet to parse element:

            JsonElement jelement = new JsonParser().parse(new InputStreamReader(in));
         // or from readed from inputStream string:
         // JsonElement jelement = new JsonParser().parse(data);
            JsonObject jobject = jelement.getAsJsonObject();
            jobject = jobject.getAsJsonObject("allergyForecast");
    

    And than you can get required values from jsonObject. Or you can check API how to get response in xml if you need only xml.