0

I need your help to parse XML announces.

Let's see the XML below :

<?xml version="1.0" encoding="UTF-8"?>
<FAVORIS>
   <LOGGED>1</LOGGED>
   <NOTICES NUM_PAGE="2">
      <NOTICE>
         <DEPARTMENT>33</DEPARTMENT>
         <SOURCE>EMP</SOURCE>
         <OBJET><![CDATA[Fourniture d'une solution régionale]]></OBJET>
         <ID_PROCEDURE>7543</ID_PROCEDURE>
         <ORGANISME><![CDATA[Gcs]]></ORGANISME>
         <TYPE_AVIS>ZZ</TYPE_AVIS>
         <TYPE_PROCEDURE>W3</TYPE_PROCEDURE>
         <CATEGORIE>Service</CATEGORIE>
         <DATE_OFFRE>16/09/2013 12:00</DATE_OFFRE>
         <DECALAGE_HORAIRE>0</DECALAGE_HORAIRE>
      </NOTICE>
      <NOTICE>
         <DEPARTMENT>33</DEPARTMENT>
         <SOURCE>EMP</SOURCE>
         <OBJET><![CDATA[Refonte du portail]]></OBJET>
         <ID_PROCEDURE>4323</ID_PROCEDURE>
         <ORGANISME><![CDATA[Mairie de W]]></ORGANISME>
         <TYPE_AVIS>Z</TYPE_AVIS>
         <TYPE_PROCEDURE>W1</TYPE_PROCEDURE>
         <CATEGORIE>Service</CATEGORIE>
         <DATE_OFFRE>03/09/2013 12:00</DATE_OFFRE>
         <DECALAGE_HORAIRE>0</DECALAGE_HORAIRE>
      </NOTICE>
....
   </NOTICES>
</FAVORIS>

To parse this XML I followed the tutorial about XML Parsing in http://developer.android.com/training/basics/network-ops/xml.html

When I parse this XML I have an error like this :

expected: START_TAG {null}NOTICES (position:START_TAG <FAVORIS>@2:10 in java.io.InputStreamReader@40e69360) 

It's due to the require but how can I resolve this issue ?

More about my code :

public class AOThumbnail_ParserXML {

private static final String ns = null;

public ArrayList<AOThumbnail> parse(String in) throws XmlPullParserException, IOException {

    Decoder decoder = new Decoder();
    String decoded_in = decoder.decode(in);

    XmlPullParser parser = Xml.newPullParser();
    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
    parser.setInput(new ByteArrayInputStream(decoded_in.getBytes()), null);
    parser.nextTag();
    return readFeed(parser);
}

private ArrayList<AOThumbnail> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
    ArrayList<AOThumbnail> entries = new ArrayList<AOThumbnail>();

    parser.require(XmlPullParser.START_TAG, ns, "NOTICES");

    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();

        // Starts by looking for the entry tag
        if (name.equals("NOTICE")) {
            entries.add(readEntry(parser));
        } else {
            skip(parser);
        }
    }
    return entries;
}

private AOThumbnail readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {

    parser.require(XmlPullParser.START_TAG, ns, "NOTICE");

    String organisme = null;
    String objet = null;
    String date_candidature = null;
    String date_offre = null;
    String departement = null;
    String source = null;
    String idProcedure = null;
    String decalageHoraire = null;

    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("ORGANISME")) {
            organisme = read(parser, "ORGANISME");
        } else if (name.equals("OBJET")) {
            objet = read(parser, "OBJET");
        } else if (name.equals("DATE_CAND")) {
            date_candidature = read(parser, "DATE_CAND");
        } else if (name.equals("DATE_OFFRE")) {
            date_offre = read(parser, "DATE_OFFRE");
        } else if (name.equals("DEPARTMENT")) {
            departement = read(parser, "DEPARTMENT");
        } else if (name.equals("SOURCE")) {
            source = read(parser, "SOURCE");
        } else if (name.equals("ID_PROCEDURE")) {
            idProcedure = read(parser, "ID_PROCEDURE");
        } else if (name.equals("DECALAGE_HORAIRE")) {
            decalageHoraire = read(parser, "DECALAGE_HORAIRE");
        } else {
            skip(parser);
        }
    }

    String date = "";
    try {
        if (date_candidature.length() > 0)
            date = date_candidature;
        else if (date_offre.length() > 0)
            date = date_offre;
        else
            date = "Se référer à l'annonce";
    } catch (Exception ex) {
        Logger.logit(ex);
    }

    return new AOThumbnail(organisme, objet, date, departement, idProcedure, source, Boolean.parseBoolean(decalageHoraire));
}

private String read(XmlPullParser parser, String balise) throws IOException, XmlPullParserException {
    parser.require(XmlPullParser.START_TAG, ns, balise);
    String content = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, balise);
    return content;
}

private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
    String result = "";
    if (parser.next() == XmlPullParser.TEXT) {
        result = parser.getText();
        parser.nextTag();
    }
    return result;
}

private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
    if (parser.getEventType() != XmlPullParser.START_TAG) {
        throw new IllegalStateException();
    }
    int depth = 1;
    while (depth != 0) {
        switch (parser.next()) {
            case XmlPullParser.END_TAG:
                depth--;
                break;
            case XmlPullParser.START_TAG:
                depth++;
                break;
        }
    }
}
}

If I parse an XML like this (see below), it works, but not with the XML above !

<NOTICES NUM_PAGE="2">
      <NOTICE>
         <DEPARTMENT>33</DEPARTMENT>
         <SOURCE>EMP</SOURCE>
         <OBJET><![CDATA[Fourniture d'une solution régionale]]></OBJET>
         <ID_PROCEDURE>7543</ID_PROCEDURE>
         <ORGANISME><![CDATA[Gcs]]></ORGANISME>
         <TYPE_AVIS>ZZ</TYPE_AVIS>
         <TYPE_PROCEDURE>W3</TYPE_PROCEDURE>
         <CATEGORIE>Service</CATEGORIE>
         <DATE_OFFRE>16/09/2013 12:00</DATE_OFFRE>
         <DECALAGE_HORAIRE>0</DECALAGE_HORAIRE>
      </NOTICE>
      <NOTICE>
         <DEPARTMENT>33</DEPARTMENT>
         <SOURCE>EMP</SOURCE>
         <OBJET><![CDATA[Refonte du portail]]></OBJET>
         <ID_PROCEDURE>4323</ID_PROCEDURE>
         <ORGANISME><![CDATA[Mairie de W]]></ORGANISME>
         <TYPE_AVIS>Z</TYPE_AVIS>
         <TYPE_PROCEDURE>W1</TYPE_PROCEDURE>
         <CATEGORIE>Service</CATEGORIE>
         <DATE_OFFRE>03/09/2013 12:00</DATE_OFFRE>
         <DECALAGE_HORAIRE>0</DECALAGE_HORAIRE>
      </NOTICE>
....
   </NOTICES>

I hope you can help me, Thanks a lot !

2 Answers 2

1

In readFeed() method, you are telling to your Parser that the current event should be an START_TAG with name "NOTICES", in other case the method will throw an Exception, which is the one you posted. Thats why the second .xml file works, but not the first (the first event of this file will be an START_TAG with name "FAVORIS").

So you should use another way to look up for the NOTICES block, you can use something like this (there are other ways to do it):

while (parser.next() != XmlPullParser.START_TAG && !(parser.getName().equals("NOTICES")));

So when this while loop ends, your parser will be at the start of the NOTICES block.

PS: I didn't test the code, so it might not work, but the solution should be similar.

Sign up to request clarification or add additional context in comments.

3 Comments

I've been resolved this issue using your tips ;) Thank you a lot
Sorry, this line is wrong, you maybe should use OR instead of AND in the while loop condition. EDIT: I've just see your answer, you're welcome!
Yes, with the AND operator the loop was an infinite loop.. lol, Thx :)
0

Issue resolved using require "FAVORIS" !

private ArrayList<AOThumbnail> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
        ArrayList<AOThumbnail> entries = new ArrayList<AOThumbnail>();

        //Go to FAVORIS' level
        parser.require(XmlPullParser.START_TAG, ns, "FAVORIS");

        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }

            String name = parser.getName();
            if(parser.getName().equals("NOTICES")) {
                //Go to NOTICES' level
                parser.require(XmlPullParser.START_TAG, ns, "NOTICES");
                //Parse on Notices' level
                return readFeed(parser);
            }

            // Starts by looking for the entry tag
            if (name.equals("NOTICE")) {
                Logger.logit("Dans notice !!!!!!");
                entries.add(readEntry(parser));
            } else {
                skip(parser);
            }
        }
        return entries;
    }

Thanks to @javi9375 for his tips ;)

Comments

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.