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), use the Builder#doc method to get
== Document Types
For more information on namespace inheritance, please see {XML::Document#namespace_inheritance}
# </soapenv:Envelope>
# <soapenv:Body/>
# <Header/>
# <soapenv:Envelope xmlns:soapenv=“schemas.xmlsoap.org/soap/envelope/”>
# => <?xml version=“1.0” encoding=“utf-8”?><br>result.doc.to_xml<br>end<br>end<br>xml.Body # users may explicitly opt into the namespace<br>xml.Header<br>xml.Envelope(“xmlns:soapenv” => “schemas.xmlsoap.org/soap/envelope/”) do
result = Nokogiri::XML::Builder.new(namespace_inheritance: false) do |xml|
to the initializer:
Users may turn this behavior off by passing a keyword argument namespace_inheritance:false
# </soapenv:Envelope>
# <soapenv:Header/>
# <soapenv:Envelope xmlns:soapenv=“schemas.xmlsoap.org/soap/envelope/”>
# => <?xml version=“1.0” encoding=“utf-8”?><br>result.doc.to_xml<br>end<br>end<br>xml.Header<br>xml.Envelope(“xmlns:soapenv” => “schemas.xmlsoap.org/soap/envelope/”) do
result = Nokogiri::XML::Builder.new do |xml|
behavior as if the underlying {XML::Document} set namespace_inheritance
to true
:
In the Builder context, children will inherit their parent’s namespace. This is the same
=== Namespace inheritance
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_css('some_tag')) do |xml|
doc = Nokogiri::XML(File.read('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)
##
def <<(string) @doc.fragment(string).children.each { |x| insert(x) } end
def [](ns)
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 } self end
def cdata(string)
##
def cdata(string) insert(doc.create_cdata(string)) end
def comment(string)
##
def comment(string) insert(doc.create_comment(string)) end
def initialize(options = {}, root = nil, &block)
...
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 @parent = @doc = related_class("Document").new end @context = nil @arity = nil @ns = nil options = DEFAULT_DOCUMENT_OPTIONS.merge(options) options.each do |k, v| @doc.send(:"#{k}=", v) end return unless block @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)
##
def insert(node, &block) node = @parent.add_child(node) if block begin old_parent = @parent @parent = node @arity ||= block.arity if @arity <= 0 instance_eval(&block) else yield(self) end ensure @parent = old_parent end end NodeBuilder.new(node, self) end
def method_missing(method, *args, &block) # :nodoc:
def method_missing(method, *args, &block) # :nodoc: if @context&.respond_to?(method) @context.send(method, *args, &block) else node = @doc.create_element(method.to_s.sub(/[_!]$/, ""), *args) do |n| # Set up the namespace if @ns.is_a?(Nokogiri::XML::Namespace) n.namespace = @ns @ns = nil end 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)
##
def text(string) insert(@doc.create_text_node(string)) end
def to_xml(*args)
##
def to_xml(*args) if Nokogiri.jruby? options = args.first.is_a?(Hash) ? args.shift : {} unless options[:save_with] options[:save_with] = Node::SaveOptions::AS_BUILDER end args.insert(0, options) end @doc.to_xml(*args) end