yeban
5/19/2010 - 1:34 PM

writer.rb

require "rubygems"
require "xml"

#add a list of namespaces to the node
#the namespaces formal parameter is a hash
#with "prefix" and "prefix_uri" as
#key, value pairs
#prefix for the default namespace is "default"
def add_namespaces( node, namespaces )
  #pass nil as the prefix to create a default node
  default = namespaces.delete( "default" )
  node.namespaces.namespace = XML::Namespace.new( node, nil, default )
  namespaces.each do |prefix, prefix_uri|
    XML::Namespace.new( node, prefix, prefix_uri )
  end
end

#add a list of attributes to the node
#the attributes formal parameter is a hash
#with "name" and "value" as
#key, value pairs
def add_attributes( node, attributes )
  attributes.each do |name, value|
    XML::Attr.new( node, name, value )
  end
end

#create a node with name
#and a hash of namespaces or attributes
#passed to options
def create_node( name, options )
  node = XML::Node.new( name )

  namespaces = options.delete( :namespaces )
  add_namespaces( node, namespaces ) if namespaces

  attributes = options.delete( :attributes )
  add_attributes( node, attributes ) if attributes
  node
end

doc = XML::Document.new
doc.encoding = XML::Encoding::ISO_8859_1

root = create_node("nexml",
                   :namespaces => { "default" => "http://www.nexml.org/1.0",
                                    "xsi" => "http://www.w3.org/2001/XMLSchema-instance",
                                    "xlink" => "http://www.w3.org/1999/xlink",
                                    "nex" => "http://www.nexml.org/1.0",
                                  },
                   :attributes => { "xsi::schemaLocation" =>
                                    "http://www.nexml.org/1.0 ../xsd/nexml.xsd",
                                    "generator" => "mesquite",
                                    "version" => "0.8"
                                  }        
                  )
default = root.namespaces.find_by_prefix( "nex" )
root.namespaces.namespace = default
doc.root = root #mark if as the root node of the doc

otus = create_node("otus",
                   :attributes => { "id" => "taxa1",
                                    "label" => "My taxa block",
                                    "xml:base" => "http://example.org/",
                                    "xml:id" => "taxa1",
                                    "class" => "taxset1",
                                    "xml:lang" => "EN" 
                                  }
                  )
root << otus #otus will be a child node of root

#create a comment node for otus
comment = <<EOF
                        The taxon element is analogous to a single label in 
			a nexus taxa block. It may have the same additional
			attributes (label, xml:base, xml:lang, xml:id, xlink:href
			and class) as the taxa element.
EOF
comment_node = XML::Node.new_comment( comment )
otus << comment_node

#create five child nodes( otu ) for the otus element
5.times do | i |
  otu = create_node("otu", :attributes => { "id" => "t#{i+1}" })
  otus << otu
end

doc.save( "sample.xml", :indent => true )