I'm trying to get the name and reading type="alpha".
I'm a beginner and English is not my first language, please pardon me. I've read about DOM, SAX, Simple, other StackOverflow posts, other samples but I don't understand and will like to learn about XMLPullParser in this case.
Sample XML below:
<feed>
<title>Title</title>
<item>
<entry>
<name>Name1</name>
<record date="20001231">
<reading type="alpha" value="100"/>
<reading type="beta" value="200"/>
</record>
</entry>
<entry>
<name>Name2</name>
<record date="20001231">
<reading type="alpha" value="300"/>
<reading type="beta" value="400"/>
</record>
</entry>
</item>
</feed>
I've read this: http://developer.android.com/training/basics/network-ops/xml.html and the sample code works for the sample XML above without the <item> tags to get the name and record date.
private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Entry> entries = new ArrayList<Entry>();
parser.require(XmlPullParser.START_TAG, ns, "feed");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
if (parser.getName().equals("entry")) {
entries.add(readEntry(parser));
} else {
skip(parser);
}
}
return entries;
}
What I've tried with the presence of <item> tags (but does not work) is:
private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Entry> entries = new ArrayList<Entry>();
parser.require(XmlPullParser.START_TAG, ns, "feed");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
if (parser.getName().equals("item")) {
parser.next();
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
if (parser.getName().equals("entry")) {
entries.add(readEntry(parser));
} else {
skip(parser);
}
}
} else {
skip(parser);
}
}
return entries;
}
If I can solve that, I will be able to read the name and record date, but what I'm trying to get is the name and reading type="alpha", which I don't know how to get the nested reading type="alpha".
Many thanks in advance.
you keep looping and when
parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("name")
you can retrive the value of the tag name with getText()
:
you will call then
parser.next();
String name = parser.getText();
when
parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("reading")
you want to read your attributes, Eg. <reading type="alpha" value="300"/>
String type = parser.getAttributeValue(null, "type");
String value = parser.getAttributeValue(null, "value");
Edit:
private void readFeed(XmlPullParser parser) throws IOException, XmlPullParserException {
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
String name = parser.getName();
if (name == null) {
continue;
}
if (name.equals("reading")) {
Log.e(getClass().getSimpleName()," " + parser.getAttributeValue(null, "type"));
Log.e(getClass().getSimpleName(), " " + parser.getAttributeValue(null, "value"));
}
}
eventType = parser.next();
}
}
You can try this function
private List readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List entries = new ArrayList();
parser.require(XmlPullParser.START_TAG, ns, "feed");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// Starts by looking for the item tag
if (name.equals("item")) {
parser.require(XmlPullParser.START_TAG, ns, "item");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
// and then get the entry here
if (name.equals("entry")) {
entries.add(readEntry(parser));
}
}
} else {
skip(parser);
}
}
return entries;
}
Where readEntry Function is :
private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "entry");
String name = null;
Record record = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("name")) {
parser.require(XmlPullParser.START_TAG, ns, "name");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "name");
} else if (name.equals("record")) {
// Try to figure it out by yourself for practice ;)
} else {
skip(parser);
}
}
return new Entry(title, summary, link);
}
I also got same error and my solution was simple just check right
String name=parser.getName();
parser.require(XmlPullParser.START_TAG, nameSpace, first_tag_key);
if name and first_tag_right is not same then you will get this exception.
THIS IS A GENERIC ANSWER FOR ANY USER IF IN CASE HE GET THIS ERROR.
The accepted answer works only because you only have nested tags but what if you had unnested tags and you only wanted the nested ones ?
One way you can do this is :
while (eventType != XmlPullParser.END_DOCUMENT ) {
// check for the parent tag
if (eventType == XmlPullParser.START_TAG && "item".equals(xpp.getName())) {
eventType = xpp.next();
// loop the parent tag elements until we reach the end of the parent tag
while (eventType != XmlPullParser.END_TAG && !"item".equals(xpp.getName())) {
// check the children tags
if ("title".equals(xpp.getName()))
// do something
else if ("link".equals(xpp.getName()))
// do something
xpp.next();
}
}
eventType = xpp.next();
}
The basic idea is one while loop for each parent tag and corresponding ifs for each children.
来源:https://stackoverflow.com/questions/33341391/difficulty-with-xml-nested-tags-with-xmlpullparser-in-android