[英]Exception during parsing XML with XMLPullParser
I need your help to parse XML announces. 我需要您的帮助来解析XML声明。
Let's see the XML below : 让我们看下面的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>
To parse this XML I followed the tutorial about XML Parsing in http://developer.android.com/training/basics/network-ops/xml.html 为了解析该XML,我遵循了http://developer.android.com/training/basics/network-ops/xml.html中有关XML解析的教程。
When I parse this XML I have an error like this : 当我解析此XML时,出现了如下错误:
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 ! 如果我解析这样的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>
I hope you can help me, Thanks a lot ! 希望您能对我有所帮助,非常感谢!
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. 在readFeed()方法中,您要告诉解析器当前事件应为名称为“ NOTICES”的START_TAG,否则,该方法将引发Exception,即您发布的异常。 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").
这就是为什么第二个.xml文件起作用,而不是第一个起作用的原因(该文件的第一个事件将是名称为“ FAVORIS”的START_TAG)。
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): 因此,您应该使用另一种方法来查找NOTICES块,可以使用类似的方法(有其他方法可以这样做):
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. 因此,当while循环结束时,解析器将位于NOTICES块的开始处。
PS: I didn't test the code, so it might not work, but the solution should be similar. PS:我没有测试代码,因此它可能无法正常工作,但是解决方案应该相似。
Issue resolved using require "FAVORIS" ! 使用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 ;) 感谢@ javi9375的技巧;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.