国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Rails 與 XML(二)

Posted in Tech at 2:18 pm by Winters Mi

轉(zhuǎn)自:http://xerdoc.com/blog/archives/190.html

我也沒想到這么快就可以開始寫第二部分,也就是在網(wǎng)站中解析XML,比如訂閱了別人的RSS等等,我們需要對其進行解析來完成自己的功能。我們都知道XML在訂閱中的作用越來越重要,從Meng Yan的一篇Subscribe using XML中就可以看到將來這種技術(shù)的發(fā)展趨勢?,F(xiàn)在也是越來越多的應用圍繞著這些XML展開,比如RSS搜索,RSS Aggregator等等。但是老實說,解析這部分沒有什么特別需要說明的,因為不管是Standalone還是Server Side的XML解析都是一樣的,就是解析嘛。但是也不應該因為沒什么可說就胡弄各位,所以,盡量找點有意思的話題來說說這部分。我也會在本文中給出一個非常非常簡單的小功能,包括了爬蟲和解析,呵呵,大話先放這里,估計看完了,不少人開始扔雞蛋了。
再說點題外話,其實老實說Rails跟XML本身聯(lián)系不是很緊密,解析XML就更沒有什么關系,不像Rails與XML第一篇中那樣,起碼Rails還提供了一個非常方便簡單的rxml模板。那這里解析XML更大程度上是Ruby的事情,所以,先解釋一下,大家別誤會,同時為了閱讀的連貫,我也就沒有改標題了。

Ruby中的XML處理器

XML處理器真的是有很多,涉及到的模型也很多,做Java的人一定知道,大大小小的XML處理器也夠你眼花繚亂的了。在Ruby中,也有不少的XML處理器,起初應該是Ruby對于native XML處理器的綁定,也就是利用native code的XML處理器,這個當然速度會比較快,但是因為應用了native code,所以移植性就會有一些影響了。那后來的一些XML處理器,使用Ruby來實現(xiàn),但是API也是非常復雜,我用過一個日本人的XML處理器,也是隨現(xiàn)在Ruby一同發(fā)布的一個,試了SAX Event的parser,試了DOM的parser,都出現(xiàn)一些問題,可能也是我不求甚解,沒有過多理會,就將目光移到了REXML上面。
我起初并沒有覺得REXML會有什么不同,直到我看到他作者的一些考慮之后,倒是覺得有點意思了,也開始學習一些深入的用法,當然現(xiàn)在還在學,呵呵。他的作者有感于目前一些XML處理器的復雜龐大,接口不良好,當然也從Java陣營參考了很多實現(xiàn)(我覺得dom4j就很龐大,我們開發(fā)桌面的時候用dom4j,整個程序的大小簡直有個質(zhì)的飛躍:(),就有了如下的考慮:

I dislike obfuscated APIs. There are several XML parser APIs for Java. Most of them follow DOM or SAX, and are very similar in philosophy with an increasing number of Java APIs. Namely, they look like they were designed by theorists who never had to use their own APIs. The extant XML APIs, in general, suck. They take a markup language which was specifically designed to be very simple, elegant, and powerful, and wrap an obnoxious, bloated, and large API around it. I was always having to refer to the API documentation to do even the most basic XML tree manipulations; nothing was intuitive, and almost every operation was complex.

REXML的作者發(fā)現(xiàn)了Electric XML(就此我才知道REXML這個名字是怎么來的,不過我沒有試用過Electric XML,有興趣的Google一下吧,呵呵)。

First, the library is small; less than 500K. Next, the API is intuitive. You want to parse a document? doc = new Document( some_file ). Create and add a new element? element = parent.addElement( tag_name ). Write out a subtree?? element.write( writer ). Now how about DOM? To parse some file: parser = new DOMParser(); parser.parse( new InputSource( new FileInputStream( some_file ) ) ) Create a new element? First you have to know the owning document of the to-be-created node (can anyone say “global variables, or obtuse, multi-argument methods”?) and call element = doc.createElement( tag_name ) parent.appendChild( element ) “appendChild”? Where did they get that from? How many different methods do we have in Java in how many different classes for adding children to parents? addElement()? add()? put()? appendChild()? Heaven forbid that you want to create an Element elsewhere in the code without having access to the owning document.

恩,我也喜歡小的開發(fā)包,我不想我的程序邏輯本來只有200k,加個包進來就變成2、3M;我也喜歡比較直觀的API,以前用jdom來生成一個表達式的XML費勁死了,我后來一般生成XML如果不涉及編碼問題的話,我都直接寫,一個表達式,一遞歸下降,得,XML樹就出來了,比appendChild快多了,有點過,呵呵,總之,直觀得API會給開發(fā)人員非常舒適得滿意度,呵呵。所以,我也就把目光放到了REXML上,而現(xiàn)在release版本得Ruby中,REXML也是隨同一起發(fā)行的,所以,用起來很方便,不用額外再去gem了。

小片段:先來看看怎么爬

回到開頭說過的那個例子,比如我要做類似Planet Eclipse這樣的RSS聚合工具或者網(wǎng)站,我就需要去訂閱相關方面的RSS,并且要去上面爬,然后解析,那么我們先看看Ruby中如何去爬這些XML源,其實也是非常簡單。Ruby的Net Module中提供了FTP、HTTP、POP、SMTP、TELNET等很多網(wǎng)絡協(xié)議的實現(xiàn),所以,很方便

  require ‘net/http‘	  h = Net::HTTP.new ‘feeds.feedburner.com‘, 80  resp, data = h.get ‘/xerdoc‘, nil  aString = ‘‘  aString += ‘Code = ‘ + resp.code.to_s + ‘<br />‘  aString += ‘Message = ‘ + resp.message + ‘<br />‘  resp.each { |key, val| aString += key + ‘ = ‘ + val + ‘<br />‘ }  aString += ‘Datagram Length : ‘+ data.length.to_s + ‘<br />‘  render_text aString  data.inspect      # real http data packet

上面一段snippet就是去爬Xerdoc的feedburner的示例,爬回來的結(jié)果就是
  Code = 200  Message = OK  last-modified = Thu, 18 Aug 2005 14:08:33 GMT  connection = close  content-type = text/xml;charset=utf-8  etag = BwYHNkx/OBe7DlAfqnqxeOKjuoE  date = Fri, 19 Aug 2005 05:36:01 GMT  server = Apache  transfer-encoding = chunked

真正的數(shù)據(jù)都在data中,當然這只是一個非常簡單的小爬蟲,真實的小爬蟲要復雜的多,要去調(diào)度,要去協(xié)調(diào)資源,不過對于一個小的展示系統(tǒng)來說,這樣就可以了,調(diào)度交給數(shù)據(jù)庫和簡單的調(diào)度代碼就可以了。

REXML的直觀API

ok,我們已經(jīng)把Xerdoc的RSS給爬回來了,該入庫加工上色了,那首先要做的當然就是解析他。
從爬蟲送回來的XML可以作為String直接傳遞給下一個工人,讓他干活,也可以存到Server Side的文件中,扔到流水線上。無論那種方式REXML的API都很直觀,解析內(nèi)容也非常簡單。
首先,當然是要引入REXML的Module,然后搞個DOM對象出來,然后就做吧:

  require ‘rexml/document‘	  #... crawler craws the data or  #... data file in the queue  doc = REXML::Document.new xmlstring  # could be xmlfile

我們前面說過Ruby本身提供的Blocks是非常強大的迭代處理工具,在加上Ruby的正則實現(xiàn)非???,據(jù)說是本地代碼。所以,REXML繼承了這些優(yōu)良特性,提供了很好的節(jié)點迭代處理,以及完整的XPath 1.0的支持,這點是REXML在API方面最直觀的方面。Ok,干活,從Xerdoc抓回來的RSS是RSS 2.0(這點我很奇怪,從Firefox中直接看的話,是Atom規(guī)范的,抓回來的就成了RSS 2.0的了),為了演示方便,我把所有文章的標題抓出來,我需要產(chǎn)生這樣的結(jié)果,

  昨夜·討論·難產(chǎn)  Rails 與 XML(一)  探討關于“壟斷工廠”的實現(xiàn)  An architecture of participation  Subscribe using XML  Xerdoc一歲了,呵呵  追星族——OpenSourceSummit  Tag your Java source code with Tiger’s annotation  Longhorn中的RSS  Dissect WordPress Plugin

那么最直接的方式就是這樣的,利用XPath直接定位到每條item的title上,

  doc.elements.each(‘rss/channel/item/title‘) { |element|     aString += subelement.text + ‘<br />‘  }

當然,這不符合解析整個Item的習慣,所以,有了這個版本,你可以在其中添加解析作者、發(fā)表日期的部分
  doc.elements.each(‘rss/channel/item‘) { |element|    element.elements.each { |subelement|      case subelement.name        when ‘title’          aString += subelement.text + ‘<br />’        when ‘pubData’          ….      end    }  }

感覺怎么樣,這樣的API是不是感覺非常的清爽,呵呵。剩下的事情也就是建立Channel的Model,然后在解析中加入對不同規(guī)范的判斷,將數(shù)據(jù)統(tǒng)一適配到Channel的模型中,入庫加工上色發(fā)表。目前有一個正在Rails中進展的開源項目,叫做FeedTools,基本上完成的就是上述工作,不過要遠比我這幾句話復雜的多,有興趣的朋友可以去參乎參乎。

我也就是說說還行,呵呵。這個系列應該是就這兩篇了,也是對自己前段學習的一段總結(jié),希望能夠?qū)Υ蠹矣兴鶐椭?/p>

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Web設計書選擇
Ruby on Rails 學習資料
rails入門書籍
Ajax 框架
Matrix - 與 Java 共舞 - AJAX:開發(fā)者新的一天
以表單為中心的Ruby on Rails面向表單編程
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服