Take the 2-minute tour ×

I'm trying to figure out why in some cases StreamingMarkupBuilder() produces non-XML. Here's how I'm calling it:

public static void saveXMLToFile(def document, String file) {
    def xmlBuilder = new StreamingMarkupBuilder().bind {
        mkp.yield document
    new File(file).withWriter { out ->
        out << xmlBuilder

And here's how we get there:

def document = new XmlParser(false, false).parse(manuscriptFile)
if (document.name().equals("appendix")) {
    def newNode = new groovy.util.Node(null, "chapter", document.attributes(), 
    XMLUtils.saveXMLToFile(newNode, manuscriptFile)

But instead of getting out XML, I get:

<?xml version='1.0'?>
title[attributes={id=_2140_5145_361}; value=[An introduction to blah]]partintro
[attributes={id=_2140_5145_362}; value=[para[attributes={id=_2140_5145_363}; value=[My 
contents, blah blah blah]]]

I've tried the docs, but unfortunately I'm not tremendously up on Groovy, so I'm sure I'm missing something simple. :(

Thanks in advance...

share|improve this question
add comment

1 Answer

up vote 6 down vote accepted

The easiest way of doing it, it seems, is using XmlUtil class, which, sadly, is not very well documented:

def saveXMLToFile(Node document, String file) {
    new File(file).withWriter { out ->
        XmlUtil.serialize(document, out)

(notice that i changed the method signature to receive a Node)

The problem i found is that groovy.xml.MarkupBuilder (or StreamingMarkupBuilder) and groovy.util.Node, which MarkupBuilder returns, don't seem to get along very well. At least i couldn't find a way of adding the XML declaration to a Node so then it could be printed with XmlNodePrinter; or adding a Node in a MarkupBuilder closure, which i guessed should be possible/easy. If anyone knows how to do any of these, plase tell it in the comments or add a new answer =D

So the second easiest solution i could find, without relying in the poorly-documented magic of XmlUtil, was printing the XML declaration first using StreamingMarkupBuilder (not even MarkupBuilder, as it seems it needs a root node declaration, which we don't want in this case) and then printing the document using XmlNodePrinter:

def saveXMLToFile(Node document, String file) {
    new File(file).withWriter { out ->
        out << new StreamingMarkupBuilder().bind { mkp.xmlDeclaration() }
        new XmlNodePrinter(new PrintWriter(out)).print(document)
share|improve this answer
Your first solution worked beautifully, thanks so much!! I'll definitely keep the second one on hand as well. –  NickChase May 6 '12 at 14:26
add comment

Your Answer


