Builder (XML)


I’ve found what appears to be a bug in the builder library, but don’t
know where to report it. The problem occurs when using indentation
(i.e. :indent > 0) and when the most deeply nested command contains a
block that returns just text, i.e. if it uses << or contains a that targets the builder object above it. This
causes the indentation to break down, placing a newline after the
opening tag, setting the text against the left margin, and then
indenting the closing tag.

The source of the problem is the loop between the block part of the
method_missing method and the _nested_structures method in xmlbase.rb.
It works if the lowest level command contains a simple text argument
(e.g., but not otherwise. I have worked around it
by redefining text!(text) as _text(text), thus switching off all
escaping of text, but that is not a fix.

It would, however, be useful to have a global option that turns off
escaping, so that one could simply use the ordinary text argument. I am
trying to produce human-readable documents, hence the indentation, and
don’t want my accented letters and typographical symbols turned into
numbers. In addition, some of my input contains presentational markup
elements, such as , etc, that should not be

I am not a professional programmer, and not good enough to offer a fix
to the problem (although I could probably manage setting up the global
option). This does, however, make me realize that thanks to Rails I am
actually doing things that I would not even have thought of attempting a
couple of years ago, so many thanks to all who work on such an excellent

Best wishes for the future.

On 23 Jun 2008, at 11:48, demo wrote:

indenting the closing tag.
Is it a case of calling _indent (which generates the spaces at the
start of a line) or of creating the new instance of XmlMarkup with the
appropriate indent and level ?
If you turn off escaping you may produce invalid xml.


Dear Fred,

I realized I should have provided some code to reproduce the bug.
This will do it:

xml = => 2) do do |n|
n << ‘Charles Dickens’

Best wishes,

On Jun 23, 11:57 pm, demo [email protected] wrote:

Dear Fred,

I realized I should have provided some code to reproduce the bug.
This will do it:

xml = => 2) do do |n|
n << ‘Charles Dickens’

This isn’t a bug. The very definition of << is that it appends text to
the output completely unmolested. Like i said you can use _indent,
_newline etc… if you want to generate that whitespace. I suppose you
could override _escape to be a no-op if you had to.




Hello Fred,

No, it’s a case of the loop only exiting properly if the last command
have a simple argument but calls another block. If there is no
then there is no extra space to put in and all appears to work fine,
but with
indentation switched on the indentation gets placed between the text
the end tag. There is no problem about the unescaped XML. It is all
produced in utf8 and validates against the DocBook 5.0 schema (the
documentation of which appears to encourage the direct entering of
unescaped text in utf8).

I have examined the code in xmlbase.rb, and the problem is clearly
ought to happen given the way the code is written, i,e,


So you get an indented start tag, a newline, no indent for the text
there is no tag to indent), and an indented end tag. If you include
within the block, then you simply shift the problem one level up.

Hope this helps. Thanks,

On Jun 23, 12:02 pm, Frederick C. [email protected]

On 24 Jun 2008, at 10:54, demo wrote:

Charles Dickens

That white space doesn’t come from <<, it’s coming from the name tag
(ie it’s assuming that after Charles dickens there would have been a
<< literally just appends the text you give it to the output. no
cleverness going on

If you add in the whitespace then it will format nicely, ie

xml = => 2) do do |n|
xml.send :_indent
n << ‘Charles Dickens’
xml.send :_newline


Charles Dickens

You could of course to redefine text!

class Builder::XmlMarkup
def text!(text)

which allows you do to do

xml = => 2) do‘charles & dickens’)

and get the following invalid markup

charles & dickens


Dear Fred,

The whole point is that it does produce the whitespace!
This is not what I want. I want nicely formatted XML
with the tags wrapped around the text, or at least
aligned. The code I showed produces:

Charles Dickens

As the level of nesting gets deeper, so the amount of
whitespace grows. Using the following:

xml = => 2) do‘Alexander Pope’)


Alexander Pope

which is what I want, except that the outpur is escaped.
I realize that this is a minor issue, but the library is
not doing what it is supposed to do.

Best wishes,

On Jun 24, 2:26 am, Frederick C. [email protected]