在任何情况下,我都会使用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
}
public class Items extends ArrayList<Item> {
public Items() {
super();
}
}
这是我们的物品容器 . 我们现在需要一个类来保存每个项目的数据 .
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.
}
例:
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;
}
}
@Override
public void characters (char [] ch, int start, int length) throws SAXException {
if (thisElement.equals ("id")) {
doc.setId (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("fam")) {
doc.setFam (new String (ch, start, length));
}
if (thisElement.equals ("name")) {
doc.setName (new String (ch, start, length));
}
if (thisElement.equals ("otc")) {
doc.setOtc (new String (ch, start, length));
}
if (thisElement.equals ("dateb")) {
doc.setDateb (new String (ch, start, length));
}
if (thisElement.equals ("datep")) {
doc.setDatep (new String (ch, start, length));
}
if (thisElement.equals ("datev")) {
doc.setDatev (new String (ch, start, length));
}
if (thisElement.equals ("datebegin")) {
doc.setDatebegin (new String (ch, start, length));
}
if (thisElement.equals ("dateend")) {
doc.setDateend (new String (ch, start, length));
}
if (thisElement.equals ("vdolid")) {
doc.setVdolid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("specid")) {
doc.setSpecid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("klavid")) {
doc.setKlavid (new Integer (new String (ch, start, length)));
}
if (thisElement.equals ("stav")) {
doc.setStav (new Float (new String (ch, start, length)));
}
if (thisElement.equals ("progid")) {
doc.setProgid (new Integer (new String (ch, start, length)));
}
}
3 回答
因此,您希望构建一个XML解析器来解析像这样的RSS提要 .
现在您可以使用两个SAX实现 . 您可以使用
org.xml.sax
或android.sax
实现 . 在发布一个简短的错误示例之后,我发现了两个人的情况 .android.sax Implementation
让我们从
android.sax
实现开始 .首先必须使用
RootElement
和Element
对象定义XML结构 .在任何情况下,我都会使用POJO(Plain Old Java Objects)来保存您的数据 . 这将是所需的POJO .
Channel.java
该类实现了
Serializable
接口,因此您可以将其放入Bundle
并对其执行某些操作 .现在我们需要一个班来保存我们的物品 . 在这种情况下,我只是要扩展
ArrayList
类 .Items.java
这是我们的物品容器 . 我们现在需要一个类来保存每个项目的数据 .
Item.java
例:
现在,这是一个非常快速的例子,你可以看到 . 使用
android.sax
SAX实现的主要优点是,您可以定义必须解析的XML的结构,然后只需将事件侦听器添加到适当的元素 . 缺点是代码变得非常重复和臃肿 .org.xml.sax Implementation
org.xml.sax
SAX处理程序实现有点不同 .在这里,您不要指定或声明XML结构,而只是监听事件 . 最广泛使用的是以下事件:
文档开始
文件结束
元素开始
元素结束
元素开始和元素结束之间的字符
使用上面的Channel对象的示例处理程序实现如下所示 .
例
说实话,我真的不能告诉你这个处理程序实现的真正优势超过了
android.sax
. 但是,我可以告诉你现在应该非常明显的劣势 . 看一下startElement
方法中的else if语句 . 由于我们有标签<title>
,link
和description
,我们必须在我们目前的XML结构中进行跟踪 . 也就是说,如果我们遇到<item>
起始标记,我们将inItem
标志设置为true
以确保我们将正确的数据映射到正确的对象,如果遇到</item>
标记,我们将endElement
标志设置为false
. 表示我们已完成该项目标记 .在这个例子中,管理它很容易,但是必须用不同级别的重复标记来解析更复杂的结构变得棘手 . 在那里你必须使用Enums来设置你当前的状态和很多switch / case statemenet来检查你的位置,或者更优雅的解决方案是使用标签栈的某种标签跟踪器 .
在许多问题中,有必要为不同目的使用不同种类的xml文件 . 我不会试图 grab 这个无边无际的东西,从我自己的经验中说出我需要的一切 .
Java,也许是我最喜欢的编程语言 . 此外,你可以通过解决任何问题并且没有必要拿出自行车这一事实来加强这种爱 .
因此,我创建了一堆运行数据库的客户端服务器,该数据库允许客户端远程在数据库服务器中创建条目 . 不用检查输入数据等等,但不是这样 .
作为工作原则,我毫不犹豫地选择了以xml文件形式传输信息 . 以下类型:
除了说它是关于医生机构的信息之外,更容易阅读 . 姓氏,名字,唯一ID等 . 一般来说,数据系列 . 此文件安全地进入服务器端,然后开始解析该文件 .
在两个选项解析(SAX vs DOM)中,我选择了SAX视图,他的工作更加明亮,而且他是第一个落入我手中的人:)
所以 . 如您所知,要成功使用解析器,我们需要覆盖所需的方法DefaultHandler . 首先,连接所需的包 .
现在我们可以开始编写解析器了
让我们从方法startDocument()开始 . 顾名思义,他对一个事件开始做出反应该文件 . 在这里你可以挂起各种动作,如内存分配,或重置值,但我们的例子非常简单,所以只需标记相应消息的工作开始:
下一个 . 解析器遍历文档符合其结构的元素 . 启动方法startElement() . 事实上,他的外观如下:startElement(String namespaceURI,String localName,String qName,Attributes atts) . 这里namespaceURI - 名称空间,localName - 元素的本地名称,qName-本地名称与名称空间(用冒号分隔)和atts的组合 - 此元素的属性 . 在这种情况下,一切都很简单 . 只需使用qName'om并将其放入某个服务行thisElement即可 . 因此,我们标记我们现在的元素 .
接下来,我们得出其含义的 Session 项目 . 这里包括方法characters() . 他的形式为:characters(char [] ch,int start,int length) . 一切都很清楚 . ch - 包含字符串本身在此元素中具有自我重要性的文件 . start和length - 指示行和长度起点的服务数 .
没错 . 我差点忘了 . 由于其目的是折叠naparsennye数据说明了医生的类型 . 该类已定义并具有所有必需的setter-getters .
下一个明显的元素结束,然后是下一个 . 负责结束endElement() . 它向我们发出信号,表明该项目已经结束,此时您可以执行任何操作 . 将继续 . 清洁元素 .
如此整个文档,我们来到文件的末尾 . 工作endDocument() . 在其中,我们可以释放内存,做一些diagnostichesuyu打印等 . 在我们的例子中,只需写下解析结束的内容 .
所以我们有一个类来解析xml我们的格式 . 这是全文:
我希望这个主题有助于轻松呈现SAX解析器的本质 .
不要严格判断第一篇文章:)我希望它至少是有用的 .
UPD:要运行此解析器,您可以使用以下代码: