Oct*_*ean 179
因此,您希望构建一个XML解析器来解析像这样的RSS提要.
<rss version="0.92">
<channel>
<title>MyTitle</title>
<link>http://myurl.com</link>
<description>MyDescription</description>
<lastBuildDate>SomeDate</lastBuildDate>
<docs>http://someurl.com</docs>
<language>SomeLanguage</language>
<item>
<title>TitleOne</title>
<description><![CDATA[Some text.]]></description>
<link>http://linktoarticle.com</link>
</item>
<item>
<title>TitleTwo</title>
<description><![CDATA[Some other text.]]></description>
<link>http://linktoanotherarticle.com</link>
</item>
</channel>
</rss>
Run Code Online (Sandbox Code Playgroud)
现在您可以使用两个SAX实现.您可以使用org.xml.sax或android.sax实施.在发布一个简短的案例之后,我将解释两者的专业和概念.
android.sax实现
让我们从android.sax实施开始.
首先必须使用RootElement和Element对象定义XML结构.
在任何情况下,我都会使用POJO(Plain Old Java Objects)来保存您的数据.这将是所需的POJO.
Channel.java
public class Channel implements Serializable {
private Items items;
private String title;
private String link;
private String description;
private String lastBuildDate;
private String docs;
private String language;
public Channel() {
setItems(null);
setTitle(null);
// set every field to null in the constructor
}
public void setItems(Items items) {
this.items = items;
}
public Items getItems() {
return items;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
// rest of the class looks similar so just setters and getters
}
Run Code Online (Sandbox Code Playgroud)
该类实现了Serializable接口,因此您可以将其放入Bundle并使用它执行某些操作.
现在我们需要一个班来保存我们的物品.在这种情况下,我只是要扩展ArrayList课程.
Items.java
public class Items extends ArrayList<Item> {
public Items() {
super();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我们的物品容器.我们现在需要一个类来保存每个项目的数据.
Item.java
public class Item implements Serializable {
private String title;
private String description;
private String link;
public Item() {
setTitle(null);
setDescription(null);
setLink(null);
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
// same as above.
}
Run Code Online (Sandbox Code Playgroud)
例:
public class Example extends DefaultHandler {
private Channel channel;
private Items items;
private Item item;
public Example() {
items = new Items();
}
public Channel parse(InputStream is) {
RootElement root = new RootElement("rss");
Element chanElement = root.getChild("channel");
Element chanTitle = chanElement.getChild("title");
Element chanLink = chanElement.getChild("link");
Element chanDescription = chanElement.getChild("description");
Element chanLastBuildDate = chanElement.getChild("lastBuildDate");
Element chanDocs = chanElement.getChild("docs");
Element chanLanguage = chanElement.getChild("language");
Element chanItem = chanElement.getChild("item");
Element itemTitle = chanItem.getChild("title");
Element itemDescription = chanItem.getChild("description");
Element itemLink = chanItem.getChild("link");
chanElement.setStartElementListener(new StartElementListener() {
public void start(Attributes attributes) {
channel = new Channel();
}
});
// Listen for the end of a text element and set the text as our
// channel's title.
chanTitle.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
channel.setTitle(body);
}
});
// Same thing happens for the other elements of channel ex.
// On every <item> tag occurrence we create a new Item object.
chanItem.setStartElementListener(new StartElementListener() {
public void start(Attributes attributes) {
item = new Item();
}
});
// On every </item> tag occurrence we add the current Item object
// to the Items container.
chanItem.setEndElementListener(new EndElementListener() {
public void end() {
items.add(item);
}
});
itemTitle.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
item.setTitle(body);
}
});
// and so on
// here we actually parse the InputStream and return the resulting
// Channel object.
try {
Xml.parse(is, Xml.Encoding.UTF_8, root.getContentHandler());
return channel;
} catch (SAXException e) {
// handle the exception
} catch (IOException e) {
// handle the exception
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这是一个非常快速的例子,你可以看到.使用android.saxSAX实现的主要优点是,您可以定义必须解析的XML的结构,然后只需将事件侦听器添加到适当的元素.缺点是代码变得非常重复和臃肿.
org.xml.sax实现
在org.xml.saxSAX处理程序实现是一个有点不同.
在这里,您不要指定或声明XML结构,而只是监听事件.最广泛使用的是以下事件:
使用上面的Channel对象的示例处理程序实现如下所示.
例
public class ExampleHandler extends DefaultHandler {
private Channel channel;
private Items items;
private Item item;
private boolean inItem = false;
private StringBuilder content;
public ExampleHandler() {
items = new Items();
content = new StringBuilder();
}
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
content = new StringBuilder();
if(localName.equalsIgnoreCase("channel")) {
channel = new Channel();
} else if(localName.equalsIgnoreCase("item")) {
inItem = true;
item = new Item();
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(localName.equalsIgnoreCase("title")) {
if(inItem) {
item.setTitle(content.toString());
} else {
channel.setTitle(content.toString());
}
} else if(localName.equalsIgnoreCase("link")) {
if(inItem) {
item.setLink(content.toString());
} else {
channel.setLink(content.toString());
}
} else if(localName.equalsIgnoreCase("description")) {
if(inItem) {
item.setDescription(content.toString());
} else {
channel.setDescription(content.toString());
}
} else if(localName.equalsIgnoreCase("lastBuildDate")) {
channel.setLastBuildDate(content.toString());
} else if(localName.equalsIgnoreCase("docs")) {
channel.setDocs(content.toString());
} else if(localName.equalsIgnoreCase("language")) {
channel.setLanguage(content.toString());
} else if(localName.equalsIgnoreCase("item")) {
inItem = false;
items.add(item);
} else if(localName.equalsIgnoreCase("channel")) {
channel.setItems(items);
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
content.append(ch, start, length);
}
public void endDocument() throws SAXException {
// you can do something here for example send
// the Channel object somewhere or whatever.
}
}
Run Code Online (Sandbox Code Playgroud)
现在说实话,我无法真正告诉你这个处理程序实现的真正优势android.sax.但是,我可以告诉你现在应该非常明显的劣势.看一下方法中的else if语句startElement.由于这样的事实,我们有标签<title>,link而description我们在XML结构,我们目前跟踪那里.也就是说,如果我们遇到一个<item>起始标记,我们设置inItem标记以true确保我们将正确的数据映射到正确的对象,并且在endElement我们设置该标记的方法中,false如果遇到</item>标记.表示我们已完成该项目标记.
在这个例子中,管理它很容易,但是必须用不同级别的重复标记来解析更复杂的结构变得棘手.在那里你必须使用Enums来设置你当前的状态和很多switch/case statemenet来检查你的位置,或者更优雅的解决方案是使用标签栈的某种标签跟踪器.
| 归档时间: |
|
| 查看次数: |
63346 次 |
| 最近记录: |