Parent

Class Index [+]

Quicksearch

Nokogiri::XML::Builder

 

Nokogiri builder can be used for building XML and HTML documents.

Synopsis:

  builder = Nokogiri::XML::Builder.new do |xml|
    xml.root {
      xml.products {
        xml.widget {
          xml.id_ "10"
          xml.name "Awesome widget"
        }
      }
    }
  end
  puts builder.to_xml

Will output:

  <?xml version="1.0"?>
  <root>
    <products>
      <widget>
        <id>10</id>
        <name>Awesome widget</name>
      </widget>
    </products>
  </root>

Builder scope

The builder allows two forms. When the builder is supplied with a block that has a parameter, the outside scope is maintained. This means you can access variables that are outside your builder. If you don’t need outside scope, you can use the builder without the “xml” prefix like this:

  builder = Nokogiri::XML::Builder.new do
    root {
      products {
        widget {
          id_ "10"
          name "Awesome widget"
        }
      }
    }
  end

Special Tags

The builder works by taking advantage of method_missing. Unfortunately some methods are defined in ruby that are difficult or dangerous to remove. You may want to create tags with the name “type”, “class”, and “id” for example. In that case, you can use an underscore to disambiguate your tag name from the method call.

Here is an example of using the underscore to disambiguate tag names from ruby methods:

  @objects = [Object.new, Object.new, Object.new]

  builder = Nokogiri::XML::Builder.new do |xml|
    xml.root {
      xml.objects {
        @objects.each do |o|
          xml.object {
            xml.type_   o.type
            xml.class_  o.class.name
            xml.id_     o.id
          }
        end
      }
    }
  end
  puts builder.to_xml

The underscore may be used with any tag name, and the last underscore will just be removed. This code will output the following XML:

  <?xml version="1.0"?>
  <root>
    <objects>
      <object>
        <type>Object</type>
        <class>Object</class>
        <id>48390</id>
      </object>
      <object>
        <type>Object</type>
        <class>Object</class>
        <id>48380</id>
      </object>
      <object>
        <type>Object</type>
        <class>Object</class>
        <id>48370</id>
      </object>
    </objects>
  </root>

Tag Attributes

Tag attributes may be supplied as method arguments. Here is our previous example, but using attributes rather than tags:

  @objects = [Object.new, Object.new, Object.new]

  builder = Nokogiri::XML::Builder.new do |xml|
    xml.root {
      xml.objects {
        @objects.each do |o|
          xml.object(:type => o.type, :class => o.class, :id => o.id)
        end
      }
    }
  end
  puts builder.to_xml

Tag Attribute Short Cuts

A couple attribute short cuts are available when building tags. The short cuts are available by special method calls when building a tag.

This example builds an “object” tag with the class attribute “classy” and the id of “thing”:

  builder = Nokogiri::XML::Builder.new do |xml|
    xml.root {
      xml.objects {
        xml.object.classy.thing!
      }
    }
  end
  puts builder.to_xml

Which will output:

  <?xml version="1.0"?>
  <root>
    <objects>
      <object class="classy" id="thing"/>
    </objects>
  </root>

All other options are still supported with this syntax, including blocks and extra tag attributes.

Namespaces

Namespaces are added similarly to attributes. Nokogiri::XML::Builder assumes that when an attribute starts with “xmlns”, it is meant to be a namespace:

  builder = Nokogiri::XML::Builder.new { |xml|
    xml.root('xmlns' => 'default', 'xmlns:foo' => 'bar') do
      xml.tenderlove
    end
  }
  puts builder.to_xml

Will output XML like this:

  <?xml version="1.0"?>
  <root xmlns:foo="bar" xmlns="default">
    <tenderlove/>
  </root>

Referencing declared namespaces

Tags that reference non-default namespaces (i.e. a tag “foo:bar”) can be built by using the Nokogiri::XML::Builder#[] method.

For example:

  builder = Nokogiri::XML::Builder.new do |xml|
    xml.root('xmlns:foo' => 'bar') {
      xml.objects {
        xml['foo'].object.classy.thing!
      }
    }
  end
  puts builder.to_xml

Will output this XML:

  <?xml version="1.0"?>
  <root xmlns:foo="bar">
    <objects>
      <foo:object class="classy" id="thing"/>
    </objects>
  </root>

Note the “foo:object” tag.

Document Types

To create a document type (DTD), access use the Builder#doc method to get the current context document. Then call Node#create_internal_subset to create the DTD node.

For example, this Ruby:

  builder = Nokogiri::XML::Builder.new do |xml|
    xml.doc.create_internal_subset(
      'html',
      "-//W3C//DTD HTML 4.01 Transitional//EN",
      "http://www.w3.org/TR/html4/loose.dtd"
    )
    xml.root do
      xml.foo
    end
  end
  
  puts builder.to_xml

Will output this xml:

  <?xml version="1.0"?>
  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  <root>
    <foo/>
  </root>

Attributes

doc[RW]

The current Document object being built

parent[RW]

The parent of the current node being built

context[RW]

A context object for use when the block has no arguments

Public Class Methods

new(options = {}) click to toggle source
 

Create a new Builder object. options are sent to the top level Document that is being built.

Building a document with a particular encoding for example:

  Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
    ...
  end
     # File lib/nokogiri/xml/builder.rb, line 266
266:       def initialize options = {}, root = nil, &block
267: 
268:         if root
269:           @doc    = root.document
270:           @parent = root
271:         else
272:           namespace     = self.class.name.split('::')
273:           namespace[1] = 'Document'
274:           @doc          = eval(namespace.join('::')).new
275:           @parent       = @doc
276:         end
277: 
278:         @context  = nil
279:         @arity    = nil
280:         @ns       = nil
281: 
282:         options.each do |k,v|
283:           @doc.send(:"#{k}=", v)
284:         end
285: 
286:         return unless block_given?
287: 
288:         @arity = block.arity
289:         if @arity <= 0
290:           @context = eval('self', block.binding)
291:           instance_eval(&block)
292:         else
293:           yield self
294:         end
295: 
296:         @parent = @doc
297:       end
with(root, &block) click to toggle source
 

Create a builder with an existing root object. This is for use when you have an existing document that you would like to augment with builder methods. The builder context created will start with the given root node.

For example:

  doc = Nokogiri::XML(open('somedoc.xml'))
  Nokogiri::XML::Builder.with(doc.at('some_tag')) do |xml|
    # ... Use normal builder methods here ...
    xml.awesome # add the "awesome" tag below "some_tag"
  end
     # File lib/nokogiri/xml/builder.rb, line 253
253:       def self.with root, &block
254:         new({}, root, &block)
255:       end

Public Instance Methods

<<(string) click to toggle source
 

Append the given raw XML string to the document

     # File lib/nokogiri/xml/builder.rb, line 335
335:       def << string
336:         @doc.fragment(string).children.each { |x| insert(x) }
337:       end
[](ns) click to toggle source
 

Build a tag that is associated with namespace ns. Raises an ArgumentError if ns has not been defined higher in the tree.

     # File lib/nokogiri/xml/builder.rb, line 314
314:       def [] ns
315:         @ns = @parent.namespace_definitions.find { |x| x.prefix == ns.to_s }
316:         return self if @ns
317: 
318:         @parent.ancestors.each do |a|
319:           next if a == doc
320:           @ns = a.namespace_definitions.find { |x| x.prefix == ns.to_s }
321:           return self if @ns
322:         end
323: 
324:         raise ArgumentError, "Namespace #{ns} has not been defined"
325:       end
cdata(string) click to toggle source
 

Create a CDATA Node with content of string

     # File lib/nokogiri/xml/builder.rb, line 307
307:       def cdata string
308:         insert(doc.create_cdata(string))
309:       end
text(string) click to toggle source
 

Create a Text Node with content of string

     # File lib/nokogiri/xml/builder.rb, line 301
301:       def text string
302:         insert @doc.create_text_node(string)
303:       end
to_xml(*args) click to toggle source
 

Convert this Builder object to XML

     # File lib/nokogiri/xml/builder.rb, line 329
329:       def to_xml(*args)
330:         @doc.to_xml(*args)
331:       end

Private Instance Methods

insert(node, &block) click to toggle source
 

Insert node as a child of the current Node

     # File lib/nokogiri/xml/builder.rb, line 357
357:       def insert(node, &block)
358:         node.parent = @parent
359:         if block_given?
360:           old_parent = @parent
361:           @parent    = node
362:           @arity ||= block.arity
363:           if @arity <= 0
364:             instance_eval(&block)
365:           else
366:             block.call(self)
367:           end
368:           @parent = old_parent
369:         end
370:         NodeBuilder.new(node, self)
371:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.