Java.lang.IndexOutOfBoundsException: Index 0 non valide, la taille est 0.. analyser le fichier incorrect?


J'essaie de créer une application Android qui analyse les images en ligne dans une grille/liste, mais j'arrive avec des erreurs d'exécution.. c'est dire que je suis en train d'analyser mal pour ma RACE DE CHIEN DE FAMILLE. Personne ne sait où je fais mes erreurs?? Je sais pourquoi un tableau serait hors limites mais je ne sais pas comment le réparer!!

J'essaie d'analyser http://www.dogbreedslist.info/family-dog-breeds / les données de ce site.. mais je reçois des erreurs d'exécution dans ces sections de mon

DogActivity.classe

  private class RetrieveDogsTask extends AsyncTask<String, Void, Void> {
       @Override
       protected Void doInBackground(String... urls) {
           for (String url : urls) {
            Parser parser = new Parser(url, DogsActivity.this);
            Breed.Name breedName = breed.getName();
            if (breedName == Breed.Name.HERDING_DOG_BREED) {
                dogs.add(parser.parseProfile(new Dog(url, breedName)));
            } else {
                dogs.addAll(parser.parseDogsPage(breedName,    DogsActivity.this));
            }
          }
        return null;
    }

Analyseur.classe

public class Parser {
Document doc;
Context context;
Elements dogRows;

public Parser(String url, Context context) {
    this.context = context;
    try {
        doc = Jsoup.connect(url).get();
    } catch (IOException e) {
        Log.e("Page", "Wrong URL or network problems", e);
    }

}

public ArrayList<Dog> parseDogsPage(Breed.Name breedName, Context context) {
    ArrayList<Dog> dogs = new ArrayList<>();
    try {
        Element dogContainer;
        if (breedName == Breed.Name.FAMILY_DOG_BREED) {
            dogContainer = doc.getElementsByClass("familybreed").get(0);
        } else {
            dogContainer = doc.getElementsByClass("toybreed").get(0);
        }
        Log.i("Page", "A page has been parsed successfully");
        dogRows = dogContainer.getElementsByTag("a");
        for (Element dogRow : dogRows) {
            String dogName, dogURL;
            Dog dog;
            dogURL = dogRow.getElementsByTag("a").get(0).absUrl("href");
            String dogThumbnailURL = dogRow.
                    getElementsByTag("img").get(0).absUrl("src");
            if (breedName == Breed.Name.FAMILY_DOG_BREED) {
                dogName = dogRow.getElementsByTag("span").get(0).text();
                dog = new Dog(dogName, dogURL, dogThumbnailURL, breedName);
            } else {
                dogName = dogRow.getElementsByTag("strong").get(0).text();
                Element details = dogContainer.getElementsByClass("details").get(0);
                Elements children = details.children();
                if (breedName == Breed.Name.TOY_DOG_BREED || breedName == Breed.Name.HOUND_DOG_BREED) {
                    String origin = children.get(1).text();
                    String lifespan = children.get(3).text();
                    dog= new Dog(dogName, origin , lifespan, dogURL, dogThumbnailURL, breedName);
                } else {
                    //for herding
                    String sizetype = children.get(1).text();
                    dog = new Dog(dogName, sizetype, dogThumbnailURL, dogURL, breedName);
                }
            }

            dogs.add(dog);
        }
    } catch (Exception e) {
        Log.e("Breed activity", "Wrong parsing for " + breedName, e);
    }
    return dogs;
}


public Dog parseProfile(Dog dog) {
    if (!dog.isDetailDataReady()) {
        //coaches already read the data in the coaches page
        try {
            Element dogContainer = doc.getElementById("dogscontainer");
            Element bioContainer = dogContainer.getElementById("biocontainer");
            Element bioDetails = bioContainer.getElementById("biodetails");
            dog.setOtherNames(bioDetails.getElementsByTag("h1").text());

            ArrayList<Dog.Detail> dogDetails = new ArrayList<>();
            Elements rows = bioDetails.getElementsByTag("tr");
            for (Element row : rows) {
                Elements tds = row.getElementsByTag("td");
                if (dog.getBreed() == Breed.Name.WORKING_DOG_BREED ||
                        dog.getBreed() == Breed.Name.TERRIER_DOG_BREED ||
                        dog.getBreed() == Breed.Name.HERDING_DOG_BREED) {
                    //coaches, manager and legends use th and td
                    Elements ths = row.getElementsByTag("th");
                    dogDetails.add(new Dog.Detail(ths.get(0).text(), tds.get(0).text()));
                } else {
                    //dogs use two tds
                    dogDetails.add(new Dog.Detail(tds.get(0).text(), tds.get(1).text()));
                }
            }
            dog.setDetails(dogDetails);

            Element articleText = dogContainer.getElementsByClass("dogarticletext").get(0);
            Elements paragraphs = articleText.getElementsByTag("p");
            String text = "";
            for (Element p : paragraphs) {
                text = text + "\n\n\n" + p.text();
            }
            dog.setArticleText(dog.getArticleText() + text);

            if (dog.getBreed() == Breed.Name.WORKING_DOG_BREED ||
                    dog.getBreed() == Breed.Name.TERRIER_DOG_BREED ||
                    dog.getBreed() == Breed.Name.HERDING_DOG_BREED) {

                //get main image url
                dog.setMainImageURL(bioContainer.getElementsByTag("img").get(0).absUrl("src"));
                if (dog.getBreed() == Breed.Name.WORKING_DOG_BREED) {
                    dog.setThumbnailURL(dog.getMainImageURL());
                    //only need first name
                    dog.setName(dog.getOtherNames().split(" ")[1]);
                }
            } else {
                dog.setMainImageURL(bioContainer.getElementsByClass("mainImage").get(0).absUrl("src"));
            }

        } catch (Exception e) {
            Log.e("Profile activity", "Wrong parsing for " + dog.getUrl(), e);
        }
        if (dog.getBreed() == Breed.Name.WORKING_DOG_BREED) {
            dog.setBasicDataReady(true);
        }
        dog.setDetailDataReady(true);
    }
    return dog;
}

}

RetrieveDogTask:

 private class RetrieveDogsTask extends AsyncTask<String, Void, Void> {
    @Override
    protected Void doInBackground(String... urls) {
        for (String url : urls) {
            Parser parser = new Parser(url, DogsActivity.this);
            Breed.Name breedName = breed.getName();
            if (breedName == Breed.Name.HERDING_DOG_BREED) {
                dogs.add(parser.parseProfile(new Dog(url, breedName)));
            } else {
                dogs.addAll(parser.parseDogsPage(breedName, DogsActivity.this));
            }
        }

        return null; 

Logcat:

 Wrong parsing for FAMILY_DOG_BREED
 java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
    at java.util.ArrayList.get(ArrayList.java:308)
  at org.jsoup.select.Elements.get(Elements.java:544)
  at com.example.shannon.popular.Parser.parseDogsPage(Parser.java:35)
           at            com.example.shannon.popular.DogsActivity$RetrieveDogsTask.doInBackground(DogsActivity.java:140)  
      at com.example.shannon.popular.DogsActivity$RetrieveDogsTask.doInBackground(DogsActivity.java:131)
       at android.os.AsyncTask$2.call(AsyncTask.java:288)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
      at    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
      at   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)

Race.classe:

public class Breed implements Serializable {
private Name name;
private String url;


Breed(Name name, String url) {
    this.name = name;
    this.url = url;
}

public Name getName() {
    return name;
}

public String getNameString(Context context) {
    String nameString = "";
    switch (name) {
        case FAMILY_DOG_BREED:
            nameString = context.getString(R.string.family_breed);
            break;
        case TOY_DOG_BREED:
            nameString = context.getString(R.string.toy_breed);
            break;
        case HOUND_DOG_BREED:
            nameString = context.getString(R.string.hound_breed);
            break;
        case TERRIER_DOG_BREED:
            nameString = context.getString(R.string.terrier_breed);
            break;
        case WORKING_DOG_BREED:
            nameString = context.getString(R.string.working_breed);
            break;
        case HERDING_DOG_BREED:
            nameString = context.getString(R.string.herding_breed);
            break;
    }
    return nameString;
}

public String getURL() {
    return url;
}

public enum Name {FAMILY_DOG_BREED, TOY_DOG_BREED, HOUND_DOG_BREED, TERRIER_DOG_BREED, WORKING_DOG_BREED, HERDING_DOG_BREED}

}

Author: coder123, 2015-10-25

1 answers

Vous utilisez peut-être un analyseur XML strict pour un document HTML mal formé. J'ai juste essayé de valider XML l'URL que vous analysez et elle échoue car l'élément <link> n'est jamais fermé (en XML strict, il devrait être terminé par une balise </link>, mais il manque dans cette page). Ceci est très courant pour les pages HTML car les navigateurs d'aujourd'hui ont tendance à corriger automatiquement ce type d'erreurs.

Puisque vous utilisez un analyseur XML strict, il est très probable que l'analyseur échoue.

Je suggère de passer à différent de l'analyseur. J'utiliserais un analyseur de TRACTION (par exemple. http://www.xmlpull.org ) - cette technique permet d'analyser avec un niveau de contrôle inférieur, ce qui signifie que vous pouvez facilement ignorer le contenu indésirable du HTML-comme ces éléments de lien, ou tout autre.

Donc vous pourriez faire quelque chose comme ceci:

XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();

parser.setInput(new BufferedReader(
                    new InputStreamReader(
                        new URL("http://.....").openConnection().getInputStream()
                    )
                )
            );

while(XmlPullParser.END_DOCUMENT != parser.next()){
    if(XmlPullParser.START_TAG == parser.getEventType()){
        String tagName = parser.getName();
        if(parser.getAttributeCount() > 0 {
             // parse attributes, if needed
        }
        if(parser.nextToken() == XmlPullParser.TEXT){
             String tagValue = parser.getText()
        }
        // etc.
    }
}
 0
Author: Andrei Marcut, 2015-10-25 17:39:25