Ruby中對XML文檔的解析

來源:互聯網
上載者:User

RUBY中對XML的文檔的解析可以使用這個庫REXML庫。

REXML庫是ruby的一個XML工具包,是使用純Ruby語言編寫的,遵守XML1.0規範。
在Ruby1.8版本及其以後,RUBY標準庫中將包含REXML。

REXML庫的路徑是: rexml/document

所有的方法和類都被封裝到一個REXML模組內。

所以使用的時候要先匯入rexml/document庫,然後把REXML模組展開到當前指令碼環境中,這樣使用REXML模組內的類就不用使用REXML::模組來引用REXML中的類了

require 'rexml/document'
include REXML

REXML有兩種方式訪問一個XML文檔,一種是樹方式,一種是流方式。

樹方式,與Javascript中的DOM方式類似,但是更加簡化,使用起來更加簡單快捷,以下就是樹方式解析XML文檔的介紹。

REXML模組裡面常用的類有以下幾個:
一 Document類

1 Document::new
Document類的構造方法,參數可以為一個xml檔案的路徑,或者一個IO對象,但必須保證該IO對象的流指標所指向的位置 到 流末尾 之間的內容,含有一篇合法的XML文檔。

2 Document#root
返回一個element類型的對象,是該xml的根項目

3 Document#version
返回當前xml文檔的版本資訊 從xml的首行中解析
如<?xml version="abcd"?>
那#version就返回'abcd',預設值是'1.0'

4 Document#encoding
返回當前xml文檔的編碼方式 同#version從xml首行讀取
如<?xml version="1.0" encode="GB2312"?>
需要注意的一個地方是,假如encode的內容是隨便輸入的,比如abc,那Documnet.new的時候,這篇xml文檔沒辦法解析。

二 Element Class
1 Element::new(arg = UNDEFINED,parent=nil,context=nil)
Element對象的建構函式。
arg:預設值是undefined,未定義,如果是一個字串的話,這個字串將做為這個元素的名稱,如果同樣也是一個element的話,會將該element複製過來,當然僅是淺層複製,也就是只複製該元素的名稱,屬性和命名空間。

parent:預設nil,是該元素的父元素。

context:預設nil。

2 Element#add_attribute( key, value = nil)
給該元素添加一個屬性,假如已經存在同名的key,則覆蓋這個key。
傳回值是value。

假如第一個參數key不是字串,而是一個Attribute類型的對象的話,第二個參數就可以省略了,會直接把該Attribute對象添加到該元素的Attribute列表中。ele = Element.new 'Book'   #<Book />
ele.add_attribute 'name', 'rubys way' #<Book name="rubys way" />
att = Attribute.new 'price', '$5'
ele.add_attribute att  #<Book name="rubys way" price="$5" />

注意上面的代碼,我先建立了att對象,然後再調用ele#add_attribute方法把att對象加到ele的attributes中去的。

3 Element#add_attributes( hash )
增加多個屬性到該元素。
hash: 可以是一個Hash或者一個二維Array。ele.add_attributes({"name" => "rubys way", "type" => "book"})#Hash
ele.add_attributes([["name","rubys way"], ["type","book"]])#array of arrays

4 Element#add_element(element, attrs=nil)
添加一個子項目到該元素,可以在添加的時候設定子項目的屬性。

element:如果是一個element,則該element被添加到該父element中,否則,將根據該參數構造一個element,比如該參數是一個string,就會構造一個新的名稱為指定的string的element加入到該元素的子項目中。

attr:如果提供了該參數,必須是一個Hash,該Hash的name將會稱為attribute的name,value就是attribute的value。

5 Element#add_namespace(prefix, uri=nil)

prefix:首碼,xmlns:prefix。

uri:內容。

如果只有一個參數的話,就沒有首碼了,直接是xmns="uri"
比如irb(main):242:0> ele = Element.new "filed"
=> <filed/>
irb(main):243:0> ele
=> <filed/>
irb(main):244:0> ele.add_namespace "pre", "uri"
=> <filed xmlns:pre='uri'/>
irb(main):245:0> ele.add_namespace "uri"
=> <filed xmlns:pre='uri' xmlns='uri'/>
irb(main):246:0> ele.add_namespace "uriuri"
=> <filed xmlns:pre='uri' xmlns='uriuri'/>

6 Element#add_text( string )
給一個Element添加text,比如:irb(main):251:0> ele = Element.new "ele"
=> <ele/>
irb(main):252:0> ele
=> <ele/>
irb(main):253:0> ele.add_text "hallo"
=> <ele>  </>
irb(main):254:0> ele.add_text " world"
=> nil
irb(main):255:0> ele
=> <ele>  </>
irb(main):256:0> ele.text
=> "hallo world"

7 Element#attribute( key )
訪問一個key,取得該key的value。

8 Element#cdatas()
擷取CData類型的數組。

9 Element#clone()
返回當前元素的淺表複製,也就是僅僅是當前元素的複製,不包括子項目。

10 Element#comments
擷取該元素的所有comment,返回一個數組。

11 Element#delete_attribute(key)
刪除指定名稱的attribute。

12 Element#delete_element(element)
刪除一個element。
參數element: 必須是element對象,或string,integer,如果是element對象,則該element對象被刪除,如果是string,則按XPATH運算式,把符合項刪除,如果是數字,則刪除指定的第幾個元素。

13 Element#delete_namespace(namespace="xmlns")
刪除指定名稱的命名空間,預設為xmlns

14 Element#document()
返回所屬的Document對象,or nil if this element doesn't belong to a document.

15 Element#each_element(xpath = nil) {|element| ...}
根據xpath指定的搜尋條件,遍曆所有符合xpath的element。

16 Element#each_element_with_attribute( key, value=nil, max=0, name=nil) {|element| ... }
根據屬性值遍曆子項目。
key參數限定了屬性的名稱,所有擁有該屬性的子項目被匹配出來
value參數限定了值。
max是匹配的個數。
name是子項目名稱。

17 Element#each_element_with_text(text=nil, max=0, name=nil) {|element| ...}
text: 符合該text的
max: 最大符合次數,設定為0為不限制。
name: 符合的子項目名稱。

18 Element#each_with_something(test, max=0, name=nil){|child if test.call(child) and num+=1 | ...}
這個方法變態不?
ruby的語言的魅力也就在這裡,很方便的給迭代方法,傳入一個作為條件的Proc。
test是一個Proc的執行個體,該Proc只有一個參數,就是每個element。
max是最大匹配數,為0時不限制。
name是名稱。

有多少個element就會調用多少次test.call。

19 Element#get_elements( xpath )
根據xpath返回一個數組,一個array,每個元素都是符合xpath的子項目。

20 Element#get_text( path=nil)
返回第一個text節點。
比如:xml = Document.new "<b>some text<c/>more text</b>" #此時xml有兩個text node
xml.root.get_text.value #-> "some text"

21 Element#has_attributes?
是否有屬性

22 Element#has_elements?
是否有子項目

23 Element#has_text?
是否有textnode

24 Element#namespace(prefix=nil)
取namespace的值,預設沒有首碼,取"xmlns"

25 Element#namespaces()
取所有的命名空間,返回一個Hash

26 Element#next_element()
取下一個element

27 Element#node_type()
取節點類型,:element或:attribute或:namespace

28 Element#prifixes
返回是一個數組,包括所有的命名空間首碼

29 Element#previous_element
返回前面的一個元素,如果沒有返回Nil。

30 Element#root
返回根項目。

31 Element#root_node
可以用這個來判斷兩個element是否是屬於同一個root的,比如ele.root_node == ele[0].root_node

32 Element#text
返回text值

33 Element#text=
設定text值

34 Element#texts
返回所有的text。
這裡有一點要說說,就是一個element可能會有多個text node,看下面的例子:ele = Document.new "<a>some string<b/>more string</a>"

ele.root.text #-> "some string"
ele.root.texts #-> ["some string","more string"]

35 Element#xpath()
擷取一個節點的xpath,這個很有用,如果你不知道該怎麼匹配一個節點,就可以直接用這個方法查看下。

三 Elements Class
element的集合,可以用element.elements來訪問子集。

1 elements::new(element)
建構函式。
element: 指示新建立的elements隸屬於哪個element。

2 elements#<<
alias for #add

3 elements#[]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.