实例解析Ruby程序中调用REXML来解析XML格式数据的用法
REXML 是由 Sean Russell 编写的库。它不是 Ruby 的唯一 XML 库,但它是很受欢迎的一个,并且是用纯 Ruby 编写( NQXML 也是用 Ruby 编写的, 但 XMLParser 封装了用 C 编写的 Jade 库)。 在他的 REXML 概述中,Russell 评论道: 示例 引用 <library shelf="Recent Acquisitions"> <section name="Ruby"> <book isbn="0672328844"> <title>The Ruby Way</title> <author>Hal Fulton</author> <description> Second edition. The book you are now reading. Ain't recursion grand? </description> </book> </section> <section name="Space"> <book isbn="0684835509"> <title>The Case for Mars</title> <author>Robert Zubrin</author> <description>Pushing toward a second home for the human race. </description> </book> <book isbn="074325631X"> <title>First Man: The Life of Neil A. Armstrong</title> <author>James R. Hansen</author> <description>Definitive biography of the first man on the moon. </description> </book> </section> </library> 1 Tree Parsing(也就是DOM-like) 我们需要require rexml/document 库,并且include REXML : require 'rexml/document' include REXML input = File.new("books.xml") doc = Document.new(input) root = doc.root puts root.attributes["shelf"] # Recent Acquisitions doc.elements.each("library/section") { |e| puts e.attributes["name"] } # Output: # Ruby # Space doc.elements.each("*/section/book") { |e| puts e.attributes["isbn"] } # Output: # 0672328844 # 0321445619 # 0684835509 # 074325631X sec2 = root.elements[2] author = sec2.elements[1].elements["author"].text # Robert Zubrin 这里要注意的是xml中的属性和值被表示为一个hash,因此我们能够通过attributes[]来提取我们需要的值,元素的值还能通过类似于path的字符串或者整数来取得.其中用整数取的话,是1-based而不是0-based. 2 Stream Parsing(也就是SAX-like Parsing) 这边使用了一个小技巧,那就是定义了一个listener 类,它将会在parse的时候被回调: require 'rexml/document' require 'rexml/streamlistener' include REXML class MyListener include REXML::StreamListener def tag_start(*args) puts "tag_start: #{args.map {|x| x.inspect}.join(',')}" end def text(data) return if data =~ /^w*$/ # whitespace only abbrev = data[0..40] + (data.length > 40 ? "..." : "") puts " text : #{abbrev.inspect}" end end list = MyListener.new source = File.new "books.xml" Document.parse_stream(source,list)
tag_start: "library",{"shelf"=>"Recent Acquisitions"} tag_start: "section",{"name"=>"Ruby"} tag_start: "book",{"isbn"=>"0672328844"} tag_start: "title",{} text : "The Ruby Way"
REXML通过XPath 类来提供Xpath的支持. 它也同时支持DOM-like和SAX-like .还是前面的那个xml文件,我们使用Xpath可以这样做: book1 = XPath.first(doc,"//book") # Info for first book found p book1 # Print out all titles XPath.each(doc,"//title") { |e| puts e.text } # Get an array of all of the "author" elements in the document. names = XPath.match(doc,"//author").map {|x| x.text } p names 输出是类似于下面的: <book isbn='0672328844'> ... </> The Ruby Way The Case for Mars First Man: The Life of Neil A. Armstrong ["Hal Fulton","Robert Zubrin","James R. Hansen"] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |