Using Builder to create XML
Builder installation Method:
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"]