Question

I'm trying to parse an XML file like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cartoonia xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <stagione nome="Cartoonia Speciale due per vedere se funziona">
        <puntata>
            <numero>0</numero>
            <titolo>Ciao Cipo</titolo>
            <link>http://www.dimaleinpentium.com/app/download/5429764359/Cartoonia+%288%5E+Puntata%29.mp3?t=1389213968</link>
            <descrizione>Ma ciao mia bella Cipo</descrizione>
        </puntata>
    </stagione> 
    <stagione nome="Stagione 1">
        <puntata>
            <numero>1</numero>
            <titolo>Puntata 1</titolo>
            <link>http://www.dimaleinpentium.com/app/download/5424302459/Cartoonia+1%5E+Puntata.mp3?t=1383736417</link>
            <descrizione>Descrizione</descrizione>
        </puntata>
        <puntata>
            <numero>2</numero>
            <titolo>Puntata 2</titolo>
            <link>http://www.dimaleinpentium.com/app/download/5425828359/Cartoonia+%282%5E+Puntata%29.mp3?t=1384351442</link>
            <descrizione>Descrizione</descrizione>
        </puntata>
        <puntata>
            <numero>3</numero>
            <titolo>Puntata 3</titolo>
            <link>http://www.dimaleinpentium.com/app/download/5427087659/Cartoonia+%283%5E+Puntata%29.mp3?t=1384981673</link>
            <descrizione>Descrizione Puntata</descrizione>
        </puntata>
    </stagione>
    <stagione nome="Cartoonia Special!">
        <puntata>
            <numero>0</numero>
            <titolo>Ciao Cipo</titolo>
            <link>http://www.dimaleinpentium.com/app/download/5429764359/Cartoonia+%288%5E+Puntata%29.mp3?t=1389213968</link>
            <descrizione>Ma ciao mia bella Cipo</descrizione>
        </puntata>
    </stagione> 
</cartoonia>

With this code (taken from AndroidDevs and modified to fit my file) I can read only first <stagione>, the others are ignored.

public Map < String, List < Entry >> 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 Map < String, List < Entry >> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
    Map < String, List < Entry >> entries = new HashMap < String, List < Entry >> ();
    String index = "";
    parser.require(XmlPullParser.START_TAG, ns, "cartoonia");
    while (parser.next() != XmlPullParser.END_TAG) {
        Log.d(TAG, "> " + parser.getLineNumber() + " <");
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        Log.d(TAG, "" + name);

        if (name.equals("stagione")) {
            index = parser.getAttributeValue(null, "nome");
            Log.d(TAG, "    " + index);
            entries.put(index, new ArrayList < Entry > ());
        } else if (name.equals("puntata")) {
            Log.d(TAG, "        Entry: " + parser.getName());
            List < Entry > en = entries.get(index);
            en.add(readEntry(parser));
        } else {
            skip(parser);
        }
    }
    return entries;
}

// Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them off
// to their respective "read" methods for processing. Otherwise, skips the tag.
private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "puntata");
    String title = null;
    String summary = null;
    String link = null;
    String number = null;

    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("titolo")) {
            title = readTitle(parser);
        } else if (name.equals("numero")) {
            number = readNumber(parser);
        } else if (name.equals("descrizione")) {
            summary = readSummary(parser);
        } else if (name.equals("link")) {
            link = readLink(parser);
        } else {
            skip(parser);
        }
    }
    return new Entry(title, number, summary, link);
}

No errors or warnings or exceptions are shown. If I change the order of the <stagione> I obtain the same results, so I don't think that it's a file's problem.

Was it helpful?

Solution

actually, i can't understand here, it's looking like you're thinking "stagione" and "puntata" are neighbour tags, but they are not neighbour, "puntata" is element of "stagione", so, you need to create another parser inside each "stagione" to read "puntata"'s

if (name.equals("stagione")) {
            index = parser.getAttributeValue(null, "nome");
            Log.d(TAG, "    " + index);
            entries.put(index, new ArrayList < Entry > ());
        } else if (name.equals("puntata")) {
            Log.d(TAG, "        Entry: " + parser.getName());
            List < Entry > en = entries.get(index);
            en.add(readEntry(parser));
        }

OTHER TIPS

The problem is your loop condition:

while (parser.next() != XmlPullParser.END_TAG) { ...

You're mixing up END_TAG with END_DOCUMENT. I'm adding you an example that could fit to your implementation. I added as many comments as I could. Take a look at this:

int eventType;

while ((eventType = parser.getEventType()) != XmlPullParser.END_DOCUMENT) {
  String current_tag = null;
  switch (eventType) {
    case XmlPullParser.START_DOCUMENT:
      // Do the pertinent initializations here (if you need, if not, just break)
      break;

    case XmlPullParser.START_TAG:
      current_tag = parser.getName();               // Get current tag
      if (current_tag.equals("cartoonia")
        continue;
      else if (current_tag.equals("stagione"))      // Initialize a new object to store a "stagione", probably add the name from "nome"
        myStagione = new WhatEver(); 
      else if (current_tag.equals("puntata"))       // Do the proper initialization to store a "puntata"
        myPuntata = new WhatEver2(); 
      else if (myPuntata != null) {                 // Just do the same!
        ...
      }

      break;

    case XmlPullParser.END_TAG:                     // This is called if you terminated processing a tag, not at the end of the XML file!
      current_tag = parser.getName();
      ...

      break;
    }

  eventType = parser.next();                        // Next event
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top