Search code examples
xmlgroovyrootmarkupbuilder

Groovy markup builder replace the root


import groovy.xml.MarkupBuilder

class XmlTest {
    static void main(def args) {
        def XmlTest s = new XmlTest()
        s.xmlTest()
    }

    def xmlTest() {
        def xml = new MarkupBuilder()
        xml.root{
            response(this.xmlClosure())
        }
    }

    def xmlClosure() {
        return {x("y")}
    }
}

The expected output is <x>y</x> I cannot modify the closure. I need to convert the closure to a XML document without adding any nodes.


Solution

  • This might help, but if you have more element types than just "x" you probably should expand on it a bit. By letting the builder write to a writer, you can take control of the result in a more controlled manner. Then, using the writer, you can extract the elements you want using a StreamingMarkupBuilder.

    It's a very roundabout way, and for very large XML structures, it may not be very efficient.

    I also took the liberty to omit the "response" element, as I didn't see that it made any sense. Feel free to put it back if you absolutely need it.

    import groovy.xml.MarkupBuilder
    import groovy.util.XmlSlurper
    import groovy.xml.StreamingMarkupBuilder
    
    class XmlTest {
        static void main(def args) {
            def sw = new StringWriter()
            println new XmlTest().xmlTest(sw)
        }
    
        def xmlTest(writer) {
            def builder = new MarkupBuilder(writer)        
            builder.root(xmlClosure())
    
            def text = new XmlSlurper().parseText(writer.toString())
    
            def outputBuilder = new StreamingMarkupBuilder()
            def result = outputBuilder.bind{ mkp.yield text.x }
            return result
        }
    
        def xmlClosure() {
            return {x("y")}
        }
    }
    

    Good luck.