Ruby程序中创建和解析XML文件的方法
使用builder创建XML builder安装方法: gem install builder require 'builder' x = Builder::XmlMarkup.new(:target => $stdout,:indent => 1) #":target =>$stdout"参数:指示输出内 容将被写向标准输出控制台 #":indent =>1"参数:XML输出形式将被缩 进一个空格字符x.instruct! :xml,:version =>'1.1',:encoding => 'gb2312' x.comment! "书本信息" x.library("shelf" => "Recent Acquisitions") { x.section("name" => "ruby"){ x.book("isbn" => "0672310001"){ x.title "Programming Ruby" x.author "Yukihiro " x.description "Programming Ruby - The Pragmatic Programmer's Guide" } } } p x #打印XML Ruby创建XML输出结果: < ?xml version="1.1" encoding="gb2312"?> < !-- 书本信息 --> < library shelf="Recent Acquisitions"> < section name="ruby"> < book isbn="0672310001"> < title>Programming Ruby< /title> < author>Yukihiro < /author> < description>Programming Ruby - The Pragmatic Programmer's Guide < /description> < /book> < /section> < /library> < inspect/> #< IO:0x2a06ae8> 使用ReXML解析XML REXML 是一个完全用ruby写的processor,他有多种api,其中两个经典的api是通过DOM-like 和SAX-like 来进行区分的。第一种是将整个文件读进内存,然后存储为一个分层的形式(也就是一棵树了).而第二种是"parse as you go",当你的文件很大,并且内存受到限制的时候,比较适合用这种。 看下面的book.xml: 引用 <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>
我们需要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
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"] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |