To include:
require 'rubygems'
require 'cheri/xml'
...
include Cheri::Xml
Note that inclusion at the top level is not recommended.
Options:
xml[:any] #=> Any tag name inside xml {} will be accepted
xml[:any=>true]
xml[:accept=>[:aaa,:bbb,:nnn]] #=> only specified tag names accepted
(see builder-builder example below for alternative approach)
xml[:format] #=> output formatted with line-feeds only
xml[:format=>true]
xml[:indent] #=> output indented by 2 spaces per level
xml[:indent=>nnn] #=> output indented by nnn spaces per level
xml[:margin=>nnn] #=> output indented by margin
#=> (in addition to :indent)
xml[:esc] #=> output will be escaped
xml[:esc=>true] #=>(off by default for performance)
# declare xxx as a namespace prefix
xml[:ns=>:xxx]
# declare xxx,yyy,zzz as namespace prefixes
xml[:ns=>[:xxx,:yyy,:zzz...]]
# declare tag aliases
xml[:alias=>[:alias1,:name1,:alias2,:name2...]]
# declare attribute aliases
xml[:attr=>[:alias1,:attr1...]]
Options specified using xml[opts] apply to all
threads for an instance.
Options specified using xml(opts) apply only to the
current thread/scope:
# example
xml[:any=>true,:indent=>2,:esc=>false]
@out = xml {
# nothing escaped at this level
aaa{
bbb {
xml(:esc) {
# text/attributes escaped in this scope
ddd { ... }
eee { ... }
}}}}
The result of an xml block will be
one of several types of object, depending on the tags used and
how they are invoked. The result object can be coerced to a
String, directly by calling its to_s
method, or indirectly by using << to append it to a
String or IO stream. The to_s method
also takes an optional String/stream parameter; for streams,
this is the most efficient way to render the XML.
# example
xml[:any,:indent]
@result = xml{
aaa(:an_attr='a value',:another=>'value 2') {
bbb { ccc }
}
}
puts @result #=> XML
@result.to_s #=> XML
a_string << @result #=> appends XML
a_stream << @result #=> appends XML
@result.to_s(a_string) #=> appends XML more efficiently
@result.to_s(a_stream) #=> appends XML more efficiently
# result:
<?xml version="1.0" encoding="UTF-8"?>
<aaa another="value 2" an_attr="a value">
<bbb>
<ccc />
</bbb>
</aaa>
To omit the XML declaration, use xml
as the receiver for the initial element:
xml.aaa{bbb}
# result
<aaa>
<bbb />
</aaa>
Alias element names that are lengthy, or can't be used directly
in Ruby:
xml[:alias=>[:cls,:class]]
xml.aaa{cls}
# result
<aaa>
<class />
</aaa>
Declare namespace prefixes, and apply them directly (using
myns.tag or myns::tag), or apply them to all elements in a
scope:
xml[:alias=>[:env,:Envelope,:hdr,:Header,:body,:Body]]
xml[:ns=>:soap]
xml { soap {
env(:xxx=>'yyy') {
hdr
body
}}}
# result
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xxx="yyy">
<soap:Header />
<soap:Body />
</soap:Envelope>
Use no_ns to turn off a namespace; or
specify a different namespace:
xml[:alias=>[:env,:Envelope,:hdr,:Header,:body,:Body]]
xml[:ns=>[:soap,:xx]]
xml {
aaa {
soap { env {
hdr
body {
no_ns {
bbb
xx::ccc
ddd
xx {eee; fff}
}}}}}}
# result
<?xml version="1.0" encoding="UTF-8"?>
<aaa>
<soap:Envelope>
<soap:Header />
<soap:Body>
<bbb />
<xx:ccc />
<ddd />
<xx:eee />
<xx:fff />
</soap:Body>
</soap:Envelope>
</aaa>
Use the Cheri builder-builder to define more explicit element
relationships:
require 'cheri/xml'
my_content_elems = [:aaa,:bbb,:ccc]
my_empty_elems = [:xxx,:yyy]
MyBuilder = Cheri::Builder.new_builder do
extend_builder Cheri::Xml
build Cheri::Xml::Elem, my_content_elems
build Cheri::Xml::EmptyElem, my_empty_elems
symbol(:aaa) { connect [:bbb,:ccc] }
symbol(:bbb) { connect :xxx }
symbol(:ccc) { connect :yyy }
# raise error to prevent non-connects from silently failing
type Cheri::Xml::XmlElement do
connect Cheri::Xml::XmlElement do |parent,child|
raise TypeError,"can't add #{child.sym} to #{parent.sym}"
end
end
end
include Cheri::Xml
include MyBuilder
Note that an upcoming feature, content models, will
provide a more straightforward (and more complete) method of
defining elements and attributes for XML and HTML, using a sort
of Rubified DTD mechanism. (This was working in an unreleased
version of Cheri, but hasn't kept up with recent refactorings.
Coming (back) soon!)
More Cheri::Xml documentation and examples coming
soon!