Я нашел пример IBM неуклюжим и грязным. Я написал свою собственную вещь для обработки RSS-каналов, ее можно адаптировать для размещения пользовательских XML-каналов.
пример использования этого:
сохраните содержимое этого фида Yahoo в файл и поместите его в свой проект. прочитать файл в строку.
String fileContents = ...;
XMLFeed feed = XMLUtils.getXmlFeed(fileContents);
теперь у вас есть объект, содержащий список каждой записи из ленты RSS
Есть 4 класса ниже. Я прокомментировал некоторые для моего же блага, но это может сбить с толку других.
По сути, DefaultHandler
просматривает строку XML для поиска общих имен RSS, таких как описание, URL, заголовок и т. Д. Он сохраняет каждую запись в своем собственном объекте и добавляет ее в основной список. константные (окончательные) поля в классе DefaultHandler
можно изменить (добавить / удалить строки), чтобы они соответствовали вашей структуре - хотя, возможно, вам также придется изменить структуру класса XmlFeedItem
.
Вы должны иметь возможность использовать это без изменений в стандартных RSS-каналах.
надеюсь, это поможет
public class XMLUtils {
public static XmlFeed getXmlFeed(String xmlString) {
XMLHandler handler = null;
try {
XMLReader xr = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
handler = new XMLHandler();
xr.setContentHandler(handler);
InputSource is = new InputSource();
is.setEncoding("UTF-8");
is.setCharacterStream(new StringReader(xmlString));
xr.parse(is);
}
catch(SAXException e) {
return null;
}
catch(ParserConfigurationException e) {
return null;
}
catch(IOException e) {
return null;
}
return handler.getXmlFeed();
}
}
public class XMLHandler extends DefaultHandler {
/**
* entity names in the XML document such as <item> which contain many fields
*/
private static final String OBJECTS[] = new String[] {"item", "entry"};
/**
* field names which correspond to a "description"
*/
private static final String DESCRIPTIONS[] = new String[] {"description", "summary"};
/**
* field names which correspond to a "url"
*/
private static final String URLS[] = new String[] {"link", "id", "guid"};
/**
* field names which correspond to "date"
*/
private static final String PUB_DATES[] = new String[] {"pubDate", "date", "updated", "published", "timestamp"};
/**
* field names which correspond to "title"
*/
private static final String TITLES[] = new String[] {"title"};
/**
* the current element being read in
*/
private String currentElement;
private boolean foundItem;
private XmlFeed xmlFeed;
private XmlFeedItem xmlFeedItem;
private String object, description, url, pubDate, title;
public XMLHandler() {
currentElement = "";
object = description = url = pubDate = title = null;
foundItem = false;
xmlFeed = new XmlFeed();
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
String s = new String(ch, start, length);
if(foundItem && s.trim().length() > 0) {
if(isFieldAvailable(currentElement, DESCRIPTIONS, description)) {
xmlFeedItem.setDescription(xmlFeedItem.getDescription() + s);
}
else if(isFieldAvailable(currentElement, URLS, url)) {
xmlFeedItem.setUrl(xmlFeedItem.getUrl() + s);
}
else if(isFieldAvailable(currentElement, PUB_DATES, pubDate)) {
xmlFeedItem.setPubDate(xmlFeedItem.getPubDate() + s);
}
else if(isFieldAvailable(currentElement, TITLES, title)) {
xmlFeedItem.setTitle(xmlFeedItem.getTitle() + s);
}
}
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if(isFieldAvailable(localName, OBJECTS, object)) {
xmlFeed.getItems().add(new XmlFeedItem(xmlFeedItem));
xmlFeedItem = new XmlFeedItem();
}
}
@Override
public void startDocument() throws SAXException {
super.startDocument();
}
/**
* @param fieldToTest the current element found in the XML string while parsing
* @param options the array of elements available to match fieldToTest to
* @param currentField the element that we're currently inside
* @return <p>if <strong>fieldToTest</strong> is contained in <strong>options</strong> and if <strong>currentField</strong>
* is either null or contained in <strong>options</strong>. This allows us to specify a number of different
* fields which mean the same thing in an XML feed. Example: <strong>summary</strong> may not be included
* in a feed but <strong>description</strong> is. Both <strong>summary</strong> and <strong>description</strong> are contained
* in the available <strong>options</strong>, so it is still matched up and used. Once one element is used
* and is contained in <strong>options</strong> it will always use the same element. <strong>currentField</strong>
* is assigned to <strong>fieldToTest</strong> if returning true and if its null(hasn't been matched before)</p>
*/
private boolean isFieldAvailable(String fieldToTest, String[] options, String currentField) {
for(String field: options) {
if(field.equalsIgnoreCase(fieldToTest) && (currentField == null || currentField.equalsIgnoreCase(field))) {
if(currentField == null) {
currentField = new String(fieldToTest);
}
return true;
}
}
return false;
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
currentElement = new String(localName);
if(!foundItem && isFieldAvailable(localName, OBJECTS, object)) {
foundItem = true;
xmlFeedItem = new XmlFeedItem();
}
}
public XmlFeed getXmlFeed() {
return xmlFeed;
}
}
public class XmlFeed {
private List<XmlFeedItem> items;
public XmlFeed() {
items = new ArrayList<XmlFeedItem>();
}
public List<XmlFeedItem> getItems() {
return items;
}
public void setItems(List<XmlFeedItem> items) {
this.items = items;
}
}
public class XmlFeedItem {
private String title;
private String description;
private String pubDate;
private String url;
public XmlFeedItem() {
title = description = pubDate = url = "";
}
public XmlFeedItem(XmlFeedItem rssFeedItem) {
this.title = rssFeedItem.getTitle();
this.description = rssFeedItem.getDescription();
this.pubDate = rssFeedItem.getPubDate();
this.url = rssFeedItem.getUrl();
}
public String getPubDate() {
return pubDate;
}
public void setPubDate(String pubDate) {
this.pubDate = pubDate;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}