回答
所以你想要構建一個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>
現在你有兩個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
}
這個類實現了Serializable
接口,這樣你就可以把它變成一個Bundle
並用它做什麼。
現在我們需要一個類來保存我們的項目。在這種情況下,我只想擴展ArrayList
類。
Items.java
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;
}
}
現在這是一個非常簡單的例子,你可以看到。使用android.sax
SAX實現的主要優點是,您可以定義必須解析的XML的結構,然後將事件偵聽器添加到適當的元素。缺點是代碼變得相當重複和臃腫。
org.xml.sax中實現
的org.xml.sax
SAX處理程序實現是一個有點不同。
在這裏,您不指定或聲明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.
}
}
現在說實話我真的不能告訴你在android.sax
一個這樣的處理程序實現的任何真正的優勢。不過,我可以告訴你現在應該顯而易見的缺點。看看startElement
方法中的else if語句。由於我們有標籤<title>
,link
和description
,所以我們必須在目前的XML結構中跟蹤這些標籤。也就是說,如果我們遇到<item>
起始標籤,我們將inItem
標誌設置爲true
以確保我們將正確的數據映射到正確的對象,並且在endElement
方法中,如果我們遇到</item>
標籤,則將該標誌設置爲false
。爲了表明我們已經完成了該物品標籤。
在這個例子中,管理起來非常容易,但必須解析更復雜的結構,並在不同級別重複標記變得棘手。在那裏,你不得不使用Enums來設置你的當前狀態,並且需要很多switch/case statemenets來檢查你的位置,或者更優雅的解決方案是使用標籤堆棧的某種標籤跟蹤器。
在許多問題中,有必要爲不同的目的使用不同種類的xml文件。我不會試圖去掌握無限的,並從我自己的經驗中得知我所需要的一切。可能是我最喜歡的編程語言。此外,這種愛情是通過你可以解決任何問題,並提出一個自行車沒有必要的事實加強。
所以,我花了很多時間創建一個運行數據庫的客戶端服務器,讓客戶端可以遠程在數據庫服務器上創建條目。不用檢查輸入數據等等,但不是那樣的。
作爲工作原理,我毫不猶豫地選擇了以xml文件形式傳輸信息。以下幾種類型:
<? xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
<doc>
<id> 3 </ id>
<fam> Ivanov </ fam>
<name> Ivan </ name>
<otc> I. </ otc>
<dateb> 10-03-2005 </ dateb>
<datep> 10-03-2005 </ datep>
<datev> 10-03-2005 </ datev>
<datebegin> 09-06-2009 </ datebegin>
<dateend> 10-03-2005 </ dateend>
<vdolid> 1 </ vdolid>
<specid> 1 </ specid>
<klavid> 1 </ klavid>
<stav> 2.0 </ stav>
<progid> 1 </ progid>
</ doc>
讓它更易於閱讀,除非說它是關於醫生機構的信息。姓氏,名字,唯一ID等等。一般來說,數據系列。該文件安全地在服務器端,然後開始解析文件。
兩個選項解析(SAX VS DOM)我選擇的是他的作品更亮的事實SAX視圖,他是第一個我掉進手中:)
所以。如您所知,爲了成功解析解析器,我們需要重寫所需的方法DefaultHandler。首先,連接所需的軟件包。
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax. *;
現在我們可以開始寫我們的分析器
public class SAXPars extends DefaultHandler {
...
}
讓我們先從方法startDocument()。顧名思義,他對文檔開始的事件作出反應。在這裏,你可以掛各種如內存分配行爲,或重置價值,但我們的例子是非常簡單的,所以只是標誌着一個適當的消息開始工作:
Override
public void startDocument() throws SAXException {
System.out.println ("Start parse XML ...");
}
下一步。解析器遍歷文檔符合其結構的元素。啓動方法startElement()。而事實上,他的外表如下:startElement(String namespaceURI,String localName,String qName,Attributes atts)。這裏namespaceURI - 命名空間,localName - 元素的本地名稱,qName - 本地名稱與命名空間的組合(用冒號分隔)和atts - 此元素的屬性。在這種情況下,所有的簡單。只需使用qName'om並將其放入某個服務行thisElement就足夠了。因此,我們標記出我們目前的元素。
@Override
public void startElement (String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
thisElement = qName;
}
接下來,我們看到會議項目的含義。這裏包括方法characters()。他具有以下形式:字符(char [] ch,int start,int length)。那麼這裏一切都很清楚。 ch - 這個元素中包含字符串本身自身重要性的文件。開始和長度 - 指示行和起始點的服務數量和長度。
@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)));
}
}
啊,是的。我差點忘了。作爲摺疊Naparsennye數據的對象將與醫生的類型進行對照。這個類被定義並具有所有必要的setter-getters。
下一個明顯的元素結束,接下來是下一個。負責結束endElement()。它向我們表明該項目已經結束,您現在可以做任何事情。將繼續。清潔元素。
@Override
public void endElement (String namespaceURI, String localName, String qName) throws SAXException {
thisElement = "";
}
即將到來的整個文件,我們來到文件的末尾。工作結束文檔()。在它裏面,我們可以釋放內存,做一些診斷,打印等等。在我們的例子中,只要寫下解析結束的內容即可。
@Override
public void endDocument() {
System.out.println ("Stop parse XML ...");
}
所以我們有一個類來解析xml我們的格式。以下是全文:
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax. *;
public class SAXPars extends DefaultHandler {
Doctors doc = new Doctors();
String thisElement = "";
public Doctors getResult() {
return doc;
}
@Override
public void startDocument() throws SAXException {
System.out.println ("Start parse XML ...");
}
@Override
public void startElement (String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
thisElement = qName;
}
@Override
public void endElement (String namespaceURI, String localName, String qName) throws SAXException {
thisElement = "";
}
@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)));
}
}
@Override
public void endDocument() {
System.out.println ("Stop parse XML ...");
}
}
我希望主題有助於很容易地提供SAX解析器的本質。
不要嚴格判斷第一篇文章:)我希望這是至少有用的。
UPD:要運行這個分析器,您可以使用此代碼:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
SAXPars saxp = new SAXPars();
parser.parse (new File ("..."), saxp);
- 1. 使用android sax解析器解析XML
- 2. 使用sax解析器解析XML
- 3. SAX XML解析器或DOM解析器?
- 4. 如何在BlackBerry中使用SAX解析器解析XML?
- 5. 如何使用SAX解析器解析android中的xml?
- 6. 如何在android中使用sax解析器從sdcard解析xml?
- 7. 使用SAX解析器,如何解析java中的xml文件
- 8. 解析XML使用SAX
- 9. 的Android - 解析使用SAX解析器
- 10. 多級XML SAX解析器
- 11. SAX解析器:從XML
- 12. 使用DOM解析器和SAX解析器進行Android XML解析的區別
- 13. 使用SAX解析器分割XML
- 14. SAX解析器。如何阻止SAX解析器連接到Internet?
- 15. 使用sax解析器解析XML for android
- 16. 使用SAX解析器進行Android XML解析
- 17. 使用sax解析器解析xml具有不同的標籤
- 18. 在SAX分析器解析XML
- 19. 使用SAX解析器
- 20. 如何使用SAX解析器
- 21. SAX解析器vs XMLPull解析器
- 22. Android SAX解析器
- 23. 解析XML字符串SAX解析器機器人
- 24. 使用SAX解析常用XML元素
- 25. SAX解析器不解析specal字符 「&」
- 26. Perl的XML :: SAX解析
- 27. SAX解析XML Android中
- 28. 安卓:SAX解析XML
- 29. 使用SAX解析解析XML已經嵌套元素
- 30. 在android中使用SAX的XML解析
能否請您發表您的XML結構的抽象描繪? – 2011-01-28 10:52:56
http://dearfriends.se/category/blog/feed/rss/ - >查看源文件 – Johan 2011-01-28 12:14:30