class Nokogiri::XML::Builder


</root>
<foo/>
<root>
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “www.w3.org/TR/html4/loose.dtd”>
<?xml version=“1.0”?>
Will output this xml:
puts builder.to_xml
end
end
xml.foo
xml.root do
)
www.w3.org/TR/html4/loose.dtd
“-//W3C//DTD HTML 4.01 Transitional//EN”,
‘html’,
xml.doc.create_internal_subset(
builder = Nokogiri::XML::Builder.new do |xml|
For example, this Ruby:
create the DTD node.
the current context document. Then call Node#create_internal_subset to
To create a document type (DTD), access use the Builder#doc method to get
== Document Types
Note the “foo:object” tag.
</root>
</objects>
<foo:object class=“classy” id=“thing”/>
<objects>
<root xmlns:foo=“bar”>
<?xml version=“1.0”?>
Will output this XML:
puts builder.to_xml
end
}
}
.object.classy.thing!
xml.objects {
xml.root(‘xmlns:foo’ => ‘bar’) {
builder = Nokogiri::XML::Builder.new do |xml|
For example:
built by using the Nokogiri::XML::Builder#[] method.
Tags that reference non-default namespaces (i.e. a tag “foo:bar”) can be
=== Referencing declared namespaces
</root>
<tenderlove/>
<root xmlns:foo=“bar” xmlns=“default”>
<?xml version=“1.0”?>
Will output XML like this:
puts builder.to_xml
}
end
xml.tenderlove
xml.root(‘xmlns’ => ‘default’, ‘xmlns:foo’ => ‘bar’) do
builder = Nokogiri::XML::Builder.new { |xml|
a namespace:
assumes that when an attribute starts with “xmlns”, it is meant to be
Namespaces are added similarly to attributes. Nokogiri::XML::Builder
== Namespaces
blocks and extra tag attributes.
All other options are still supported with this syntax, including
</root>
</objects>
<object class=“classy” id=“thing”/>
<objects>
<root>
<?xml version=“1.0”?>
Which will output:
puts builder.to_xml
end
}
}
xml.object.classy.thing!
xml.objects {
xml.root {
builder = Nokogiri::XML::Builder.new do |xml|
and the id of “thing”:
This example builds an “object” tag with the class attribute “classy”
short cuts are available by special method calls when building a tag.
A couple attribute short cuts are available when building tags. The
=== Tag Attribute Short Cuts
puts builder.to_xml
end
}
}
end
xml.object(:type => o.type, :class => o.class, :id => o.id)
@objects.each do |o|
xml.objects {
xml.root {
builder = Nokogiri::XML::Builder.new do |xml|
@objects = [Object.new, Object.new, Object.new]
previous example, but using attributes rather than tags:
Tag attributes may be supplied as method arguments. Here is our
== Tag Attributes
</root>
</objects>
</object>
<id>48370</id>
<class>Object</class>
<type>Object</type>
<object>
</object>
<id>48380</id>
<class>Object</class>
<type>Object</type>
<object>
</object>
<id>48390</id>
<class>Object</class>
<type>Object</type>
<object>
<objects>
<root>
<?xml version=“1.0”?>
will just be removed. This code will output the following XML:
The underscore may be used with any tag name, and the last underscore
puts builder.to_xml
end
}
}
end
}
xml.id_ o.id
xml.class_ o.class.name
xml.type_ o.type
xml.object {
@objects.each do |o|
xml.objects {
xml.root {
builder = Nokogiri::XML::Builder.new do |xml|
@objects = [Object.new, Object.new, Object.new]
ruby methods:
Here is an example of using the underscore to disambiguate tag names from
disambiguate your tag name from the method call.
“id” for example. In that case, you can use an underscore to
remove. You may want to create tags with the name “type”, “class”, and
some methods are defined in ruby that are difficult or dangerous to
The builder works by taking advantage of method_missing. Unfortunately
== Special Tags
end
}
}
}
name “Awesome widget”
id_ “10”
widget {
products {
root {
builder = Nokogiri::XML::Builder.new do
this:
outside scope, you can use the builder without the “xml” prefix like
can access variables that are outside your builder. If you don’t need
that has a parameter, the outside scope is maintained. This means you
The builder allows two forms. When the builder is supplied with a block
=== Builder scope
</root>
</products>
</widget>
<name>Awesome widget</name>
<id>10</id>
<widget>
<products>
<root>
<?xml version=“1.0”?>
Will output:
puts builder.to_xml
end
}
}
}
xml.name “Awesome widget”
xml.id_ “10”
xml.widget {
xml.products {
xml.root {
builder = Nokogiri::XML::Builder.new do |xml|
== Synopsis:
Nokogiri builder can be used for building XML and HTML documents.
##

def self.with root, &block


end
xml.awesome # add the "awesome" tag below "some_tag"
# ... Use normal builder methods here ...
Nokogiri::XML::Builder.with(doc.at('some_tag')) do |xml|
doc = Nokogiri::XML(open('somedoc.xml'))

For example:

given +root+ node.
builder methods. The builder context created will start with the
you have an existing document that you would like to augment with
Create a builder with an existing root object. This is for use when
##
def self.with root, &block
  new({}, root, &block)
end

def << string

Append the given raw XML +string+ to the document
##
def << string
  @doc.fragment(string).children.each { |x| insert(x) }
end

def [] ns

ArgumentError if +ns+ has not been defined higher in the tree.
Build a tag that is associated with namespace +ns+. Raises an
##
def [] ns
  if @parent != @doc
    @ns = @parent.namespace_definitions.find { |x| x.prefix == ns.to_s }
  end
  return self if @ns
  @parent.ancestors.each do |a|
    next if a == doc
    @ns = a.namespace_definitions.find { |x| x.prefix == ns.to_s }
    return self if @ns
  end
  @ns = { :pending => ns.to_s }
  return self
end

def cdata string

Create a CDATA Node with content of +string+
##
def cdata string
  insert doc.create_cdata(string)
end

def comment string

Create a Comment Node with content of +string+
##
def comment string
  insert doc.create_comment(string)
end

def initialize options = {}, root = nil, &block

end
...
Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|

Building a document with a particular encoding for example:

Document that is being built.
Create a new Builder object. +options+ are sent to the top level
##
def initialize options = {}, root = nil, &block
  if root
    @doc    = root.document
    @parent = root
  else
    namespace     = self.class.name.split('::')
    namespace[-1] = 'Document'
    @doc          = eval(namespace.join('::')).new
    @parent       = @doc
  end
  @context  = nil
  @arity    = nil
  @ns       = nil
  options.each do |k,v|
    @doc.send(:"#{k}=", v)
  end
  return unless block_given?
  @arity = block.arity
  if @arity <= 0
    @context = eval('self', block.binding)
    instance_eval(&block)
  else
    yield self
  end
  @parent = @doc
end

def insert(node, &block)

Insert +node+ as a child of the current Node
##
def insert(node, &block)
  node = @parent.add_child(node)
  if block_given?
    old_parent = @parent
    @parent    = node
    @arity ||= block.arity
    if @arity <= 0
      instance_eval(&block)
    else
      block.call(self)
    end
    @parent = old_parent
  end
  NodeBuilder.new(node, self)
end

def method_missing method, *args, &block # :nodoc:

:nodoc:
def method_missing method, *args, &block # :nodoc:
  if @context && @context.respond_to?(method)
    @context.send(method, *args, &block)
  else
    node = @doc.create_element(method.to_s.sub(/[_!]$/, ''),*args) { |n|
      # Set up the namespace
      if @ns.is_a? Nokogiri::XML::Namespace
        n.namespace = @ns
        @ns = nil
      end
    }
    if @ns.is_a? Hash
      node.namespace = node.namespace_definitions.find { |x| x.prefix == @ns[:pending] }
      if node.namespace.nil?
        raise ArgumentError, "Namespace #{@ns[:pending]} has not been defined"
      end
      @ns = nil
    end
    insert(node, &block)
  end
end

def text string

Create a Text Node with content of +string+
##
def text string
  insert @doc.create_text_node(string)
end

def to_xml(*args)

Convert this Builder object to XML
##
def to_xml(*args)
  if Nokogiri.jruby?
    options = args.first.is_a?(Hash) ? args.shift : {}
    if !options[:save_with]
      options[:save_with] = Node::SaveOptions::AS_BUILDER
    end
    args.insert(0, options)
  end
  @doc.to_xml(*args)
end