/* * Copyright 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.basicsyncadapter.net; import android.text.format.Time; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.InputStream; import java.text.ParseException; import java.util.ArrayList; import java.util.List; /** * This class parses generic Atom feeds. * *
Given an InputStream representation of a feed, it returns a List of entries, * where each list element represents a single entry (post) in the XML feed. * *
An example of an Atom feed can be found at:
* http://en.wikipedia.org/w/index.php?title=Atom_(standard)&oldid=560239173#Example_of_an_Atom_1.0_feed
*/
public class FeedParser {
// Constants indicting XML element names that we're interested in
private static final int TAG_ID = 1;
private static final int TAG_TITLE = 2;
private static final int TAG_PUBLISHED = 3;
private static final int TAG_LINK = 4;
// We don't use XML namespaces
private static final String ns = null;
/** Parse an Atom feed, returning a collection of Entry objects.
*
* @param in Atom feed, as a stream.
* @return List of {@link com.example.android.basicsyncadapter.net.FeedParser.Entry} objects.
* @throws org.xmlpull.v1.XmlPullParserException on error parsing feed.
* @throws java.io.IOException on I/O error.
*/
public List You probably want to call readTag().
*
* @param parser Current parser object
* @param tag XML element tag name to parse
* @return Body of the specified tag
* @throws java.io.IOException
* @throws org.xmlpull.v1.XmlPullParserException
*/
private String readBasicTag(XmlPullParser parser, String tag)
throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, tag);
String result = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, tag);
return result;
}
/**
* Processes link tags in the feed.
*/
private String readAlternateLink(XmlPullParser parser)
throws IOException, XmlPullParserException {
String link = null;
parser.require(XmlPullParser.START_TAG, ns, "link");
String tag = parser.getName();
String relType = parser.getAttributeValue(null, "rel");
if (relType.equals("alternate")) {
link = parser.getAttributeValue(null, "href");
}
while (true) {
if (parser.nextTag() == XmlPullParser.END_TAG) break;
// Intentionally break; consumes any remaining sub-tags.
}
return link;
}
/**
* For the tags title and summary, extracts their text values.
*/
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = null;
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
/**
* Skips tags the parser isn't interested in. Uses depth to handle nested tags. i.e.,
* if the next tag after a START_TAG isn't a matching END_TAG, it keeps going until it
* finds the matching END_TAG (as indicated by the value of "depth" being 0).
*/
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;
}
}
}
/**
* This class represents a single entry (post) in the XML feed.
*
* It includes the data members "title," "link," and "summary."
*/
public static class Entry {
public final String id;
public final String title;
public final String link;
public final long published;
Entry(String id, String title, String link, long published) {
this.id = id;
this.title = title;
this.link = link;
this.published = published;
}
}
}