XmlPullParser для обработки многомерных повторяющихся элементов
Я пытаюсь получить список элементов верхнего уровня из моего XML (который содержит дублированные подэлементы)
пример XML
<feed>
<folder name="subfolder1">
<file name="subfile1" />
<file name="subfile2" />
<folder name="subsubfolder1">
<file name="subsubfile1" />
<file name="subsubfile2" />
</folder>
</folder>
<folder name="subfolder2">
<file name="subfile1" />
<file name="subfile2" />
<folder name="subsubfolder1">
<file name="subsubfile1" />
<file name="subsubfile2" />
</folder>
</folder>
<file name="file1"/>
</feed>
Я пытаюсь получить список всех имен элементов верхнего уровня, например
.subfolder1
.subfolder2
Вот мой FeedReader....
private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Entry> entries = new ArrayList<Entry>();
Log.v("ab", "reed feed started");
parser.require(XmlPullParser.START_TAG, ns, "feed");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String sectionName = parser.getName();
if(sectionName.equals("folder")) {
readFolder(parser);
}
}
return entries;
}
private void readFolder (XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "folder");
Log.v("ab", parser.getAttributeValue(null, "name"));
parser.require(XmlPullParser.END_TAG, ns, "folder");
}
А вот и мой LogCat....
09-02 13:40:22.537 31736-31753/? V/ab reed feed started
09-02 13:40:22.537 31736-31753/? V/ab﹕ subfolder1
Может кто-нибудь помочь с тем, почему это останавливается после нахождения первого экземпляра элемента папки?
1 ответ
Это похоже на проблему с вашей последней строкой parser.require:
parser.require(XmlPullParser.END_TAG, ns, "folder");
Из документации вы здесь проверяете, выполняются ли эти условия, а если нет, выдает исключение. Таким образом, вы в настоящее время находитесь в начальном теге "папки", который только что прочитали, и проверяете, находитесь ли вы в конечном теге "папки". Поскольку вы не находитесь в конце тега "folder", то parser.require выдаст исключение.
Если вы удалите эту строку, она должна просто позволить вашему циклу while продолжаться до следующего тега запуска папки.
Изменить: вот полное решение
Нам нужно продолжать работу до конца документа, а не только до END_TAG, поэтому я изменил ваш цикл while while (parser.next() != XmlPullParser.END_DOCUMENT)
, а затем добавил дополнительный код после вызова метода readFolder. Если я правильно понял, вы только после папок с именем "подпапки" и пропуская "подпапки". Так что я включил цикл, который должен их пропустить. Я также удалил строки parser.require, так как лично не видел необходимости, но это только один из способов сделать это.
private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Entry> entries = new ArrayList<Entry>();
Log.v("ab", "reed feed started");
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String sectionName = parser.getName();
if(sectionName.equals("folder")) {
readFolder(parser);
//these booleans will be used to help us skip the subfolders
boolean finishedTopLevelElement = false;
boolean unwantedSubFolderFound = false;
//this will loop until we are at a "folder" tag and have
//confirmed we have finished with the top level folder
while (!(("folder".equals(parser.getName())) && finishedTopLevelElement)){
parser.next();
//we only care about 'folder' tags, for anything else
//we keep looping
if ("folder".equals(parser.getName())){
if (parser.getEventType() == XmlPullParser.START_TAG){
//if we hit a folder start tag, we're at a sub-folder
unwantedSubFolderFound = true;
} else if (parser.getEventType() == XmlPullParser.END_TAG && !unwantedSubFolderFound){
//if we hit a 'folder' end tag and we've not got an unwanted subfolder then
//we're done, it's the end tag of the top-level folder
finishedTopLevelElement = true;
unwantedSubFolderFound = false;
} else {
//if it's a folder end tag and we HAVE previously found an unwanted sub folder start tag
//then we've successfully skipped that sub-folder and can keep looking
unwantedSubFolderFound = false;
}
}
}
}
}
return entries;
}
private void readFolder (XmlPullParser parser) throws XmlPullParserException, IOException {
Log.v("ab", parser.getAttributeValue(null, "name"));
}