簡體   English   中英

使用XMLPullParser解析XML時發生異常

[英]Exception during parsing XML with XMLPullParser

我需要您的幫助來解析XML聲明。

讓我們看下面的XML:

<?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>

為了解析該XML,我遵循了http://developer.android.com/training/basics/network-ops/xml.html中有關XML解析的教程。

當我解析此XML時,出現了如下錯誤:

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

這是由於需要,但我該如何解決呢?

有關我的代碼的更多信息:

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;
        }
    }
}
}

如果我解析這樣的XML(請參見下文),則可以工作,但不能與上述XML一起使用!

<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>

希望您能對我有所幫助,非常感謝!

在readFeed()方法中,您要告訴解析器當前事件應為名稱為“ NOTICES”的START_TAG,否則,該方法將引發Exception,即您發布的異常。 這就是為什么第二個.xml文件起作用,而不是第一個起作用的原因(該文件的第一個事件將是名稱為“ FAVORIS”的START_TAG)。

因此,您應該使用另一種方法來查找NOTICES塊,可以使用類似的方法(有其他方法可以這樣做):

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

因此,當while循環結束時,解析器將位於NOTICES塊的開始處。

PS:我沒有測試代碼,因此它可能無法正常工作,但是解決方案應該相似。

使用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;
    }

感謝@ javi9375的技巧;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM