Ways to create and parse XML files in Ruby programs _ruby topics

Source: Internet
Author: User
Tags xpath

Using Builder to create XML

Builder installation Method:

Gem Install Builder
Require ' builder '  
 
x = builder::xmlmarkup.new (: Target =>
 $stdout,: Indent => 1) 
# ": Target => $stdout" Parameters: Indicates that the output
will be written to the standard output console 
# ": Indent =>1" parameter: The XML output form will be indented
into a space character x.instruct!: XML,
: Version => ' 1.1 ',: Encoding => ' gb2312 ' 
x.comment! Book Info 
 
x.library ("shelf" => "recent acquisitions") { 
x.section ("name" => "Ruby") { 
X.book ("ISBN") => "0672310001") { 
x.title "programming Ruby"  
x.author "Yukihiro" 
x.description "programming Ruby-< C18/>the Pragmatic Programmer ' s Guide '}} 
 

P x #打印XML

Ruby creates XML output results:

< XML version= "1.1" encoding= "gb2312"?> 
<!--book information--> 
< 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> 

Parsing XML using Rexml

Rexml is a processor written entirely in Ruby, with a variety of APIs, two classic APIs that are distinguished by dom-like and sax-like. The first is to read the entire file into memory and then store it as a layered form (that is, a tree). The second is "parse as you Go", which is more appropriate when your files are large and memory is limited.

Look at the following book.xml:

Reference

<library shelf= "recent acquisitions" > <section name= "Ruby" > <book isbn= "0672328844" > <t Itle>the Ruby way</title> <author>hal fulton</author> <description> Second EDI tion. 
      The book is 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> <des 
      Cription>pushing toward a second home for the human race. </description> </book> <book isbn= "074325631X" > <title>first man:the Life of Nei L. armstrong</title> <author>james R. hansen</author> <description>definitive Biog 
      Raphy of the "the" the Moon. </description> </book> </section> </liBrary>
 


1 tree parsing (i.e. dom-like)

We need require rexml/document libraries, and 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 


The note here is that the attributes and values in XML are represented as a hash, so we can extract the values we need through attributes[]. The value of an element can also be obtained by means of a string or an integer similar to path. It is 1-based rather than 0-based, with integers.

2 Stream parsing (i.e. Sax-like parsing)

Here's a little trick that defines a listener class that will be called back at 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 to 
  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) 


Here's an introduction to the Streamlistener module, which provides a few empty callback methods, so you can override it to achieve your own functionality. When parser enters a tag, it calls Tag_ The Start method. And the text method is similar, he only is when reads the data to be recalled, its output is this:

Tag_start: "Library", {"shelf" => "recent Acquisitions"} 
Tag_start: "section", {"name" => "Ruby"} 
tag_ Start: "book", {"ISBN" => "0672328844"} 
Tag_start: "title", {} 
 text  :  "The Ruby Way" 
......................................... 


3 XPath

Rexml provides XPath support through an XPath class. It also supports Dom-like and sax-like. or the previous XML file, which we use XPath to do:

Book1 = Xpath.first (Doc, "//book") # Info for a-i-  found 
p book1 
 
# Print out all titles 
Xpath.each (d OC, "//title") {|e| puts e.text} # Get a array of all of 
 
the ' author ' elements in the document. 
names = Xpath.match (Doc, "//author"). Map {|x| X.text} 
p names 


The output is similar to the following:

<book isbn= ' 0672328844 ' > ... </> the Ruby Way the case for 
Mars 
-A-man:the life of Neil A. Armstrong 
["Hal Fulton", "Robert Zubrin", "James R. Hansen"] 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.