Class: Xbuilder
- Inherits:
-
BlankSlate
- Object
- BlankSlate
- Xbuilder
- Defined in:
- lib/xbuilder.rb
Overview
Usage
Xbuilder supports almost all of the Builder’s features. Here is a small example:
xml = Xbuilder.new(indent: 2)
xml.node attr: 1 do |xml| #=> <node attr="1">
xml.ns :child, attr: 2 #=> <ns:child attr="2"/>
end #=> </node>
Direct Known Subclasses
Constant Summary collapse
- XML =
:nodoc:
::LibXML::XML
Instance Method Summary collapse
-
#<<(text, escape = false) ⇒ Object
Append text to the output.
-
#cdata!(text) ⇒ Object
Insert CDATA node.
-
#comment!(comment_text) ⇒ Object
Insert comment node.
-
#declare!(inst, *args, &block) ⇒ Object
XML declarations are not yet supported.
-
#initialize(options = {}) ⇒ Xbuilder
constructor
Create an XML builder.
-
#instruct!(*args) ⇒ Object
Custom XML instructions are not supported.
-
#method_missing(name, *args, &block) ⇒ Object
Append a tag with the method’s name to the output.
-
#tag!(name, *args, &block) ⇒ Object
Append a tag to the output.
-
#target! ⇒ Object
Returns the target XML string.
-
#text!(text, escape = true) ⇒ Object
Append text to the output.
Constructor Details
#initialize(options = {}) ⇒ Xbuilder
Create an XML builder. Available options are:
- :root
-
Root element. All nodes created by the builder will be attached to it.
- :encoding
-
Document encoding, e.g. “UTF-8”. Will be used in XML instruction:
<?xml version="1.0" encoding="UTF-8"?>
Builder compatibility options:
- :indent
-
Number of spaces used for indentation. Default is 0.
- :margin
-
Amount of initial indentation (specified in levels, not spaces).
28 29 30 31 32 33 34 35 36 37 |
# File 'lib/xbuilder.rb', line 28 def initialize( = {}) if [:target] ::Kernel.raise ::ArgumentError, "':target' option is not supported." end @indent = [:indent].to_i @margin = [:margin].to_i @root = [:root] || XML::Document.new @encoding = [:encoding] || "UTF-8" end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
Append a tag with the method’s name to the output.
xml.node { |xml| xml.child } #=> <node><child/></node>
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/xbuilder.rb', line 41 def method_missing(name, *args, &block) name = "#{name}:#{args.shift}" if args.first.kind_of?(::Symbol) node = XML::Node.new(name.to_s) text = nil args.each do |arg| case arg when ::Hash arg.each do |key, val| k = key.to_s v = val.to_s node[k] = v end else text ||= '' text << arg.to_s end end if block && text ::Kernel.raise ::ArgumentError, "Cannot mix a text argument with a block" end # FIXME `__escape` is a temp solution till bugfix release. # https://github.com/xml4r/libxml-ruby/pull/46 node.content = __escape(text) if text if block unless block.arity > 0 ::Kernel.raise ::ArgumentError, "Provide at least 1 block argument: `xml.node { |xml| xml.child }'" end block.call(__new_instance(root: node)) end __append_node(node) end |
Instance Method Details
#<<(text, escape = false) ⇒ Object
Append text to the output. Do not escape by default.
xml.node { xml << "unescaped & text" } #=> <node>unescaped & text</node>
97 98 99 100 |
# File 'lib/xbuilder.rb', line 97 def <<(text, escape = false) __ensure_no_block(::Kernel.block_given?) text!(text, escape) end |
#cdata!(text) ⇒ Object
Insert CDATA node.
139 140 141 142 143 |
# File 'lib/xbuilder.rb', line 139 def cdata!(text) __ensure_no_block(::Kernel.block_given?) node = XML::Node.new_cdata(text) __append_node(node) end |
#comment!(comment_text) ⇒ Object
Insert comment node.
120 121 122 123 124 |
# File 'lib/xbuilder.rb', line 120 def comment!(comment_text) __ensure_no_block(::Kernel.block_given?) node = XML::Node.new_comment(comment_text) __append_node(node) end |
#declare!(inst, *args, &block) ⇒ Object
XML declarations are not yet supported.
127 128 129 |
# File 'lib/xbuilder.rb', line 127 def declare!(inst, *args, &block) __warn("XML declarations are not yet supported. Pull requests are welcome!") end |
#instruct!(*args) ⇒ Object
Custom XML instructions are not supported. Left here for Builder API compatibility.
133 134 135 136 |
# File 'lib/xbuilder.rb', line 133 def instruct!(*args) # TODO should we switch XML instruction off if `instruct!` is not called? __warn("Custom XML instructions are not supported") end |
#tag!(name, *args, &block) ⇒ Object
Append a tag to the output. The first argument is a tag name. The rest of arguments are the same as method_missing
ones.
xml.tag!("node") { |xml| xml.tag!("child") } #=> <node><child/></node>
81 82 83 |
# File 'lib/xbuilder.rb', line 81 def tag!(name, *args, &block) method_missing(name, *args, &block) end |
#target! ⇒ Object
Returns the target XML string.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/xbuilder.rb', line 103 def target! # FIXME Temp solution for encoding constant lookup. # (till bugfix release https://github.com/xml4r/libxml-ruby/pull/45 to be published) const_name = @encoding.upcase.gsub!("-", "_") encoding = XML::Encoding.const_get(const_name) XML.indent_tree_output = (@indent > 0) XML.default_tree_indent_string = (" " * @indent) @root.to_s(encoding: encoding, indent: XML.indent_tree_output).tap do |xml| if @margin > 0 xml.gsub!(/^/, (" " * @indent) * @margin) end end end |
#text!(text, escape = true) ⇒ Object
Append text to the output. Escape by default.
xml.node { xml.text!("escaped & text") } #=> <node>escaped & text</node>
88 89 90 91 92 93 |
# File 'lib/xbuilder.rb', line 88 def text!(text, escape = true) __ensure_no_block(::Kernel.block_given?) node = XML::Node.new_text(text) node.output_escaping = escape __append_node(node) end |