xmlgroovymarkupbuilder

How to convince groovy.xml.MarkupBuilder to create a node whose name is 'use'


SVG defines an element named use and I am trying to generate an SVG file using groovy.xml.MarkupBuilder that takes advantage of this tag:

http://tutorials.jenkov.com/svg/defs-element.html

def writer = new StringWriter()
def xml = new MarkupBuilder(writer)

xml.svg {
    defs {
        g(id:"shape") {
            rect(x:50, y:50, width:50, height:50)
            circle(cx:50, cy:50, r:50)
        }
    }

    use("xlink:href":"#shape", x:50,  y:50")
}

However use is also a keyword in groovy. How do I escape it correctly?


Solution

  • not sure those methods are official however they work:

    v1:

    def xml = new groovy.xml.MarkupBuilder()
    
    xml.svg {
        defs {
            g(id:"shape") {
                rect(x:50, y:50, width:50, height:50)
                circle(cx:50, cy:50, r:50)
            }
        }
        createNode('use',["xlink:href":"#shape", x:50,  y:50])
        //nested elements could be here
        nodeCompleted('svg','use')
    }
    

    v2:

    def xml = new groovy.xml.MarkupBuilder()
    
    xml.svg {
        defs {
            g(id:"shape") {
                rect(x:50, y:50, width:50, height:50)
                circle(cx:50, cy:50, r:50)
            }
        }
    
        doInvokeMethod('use','use',[["xlink:href":"#shape", x:50,  y:50], { 
            /*nested elements could be here*/ 
        } ])
    }
    

    v3:

    we could redefine getName method that is responsible to do names mapping or check escaping rules.

    @groovy.transform.CompileStatic
    class MyMarkupBuilder  extends groovy.xml.MarkupBuilder{
        def getName(String name){
            if(name.startsWith('__'))return name.substring(2)
            return name
        }
    }
    
    def xml = new MyMarkupBuilder()
    
    xml.svg {
        defs {
            g(id:"shape") {
                rect(x:50, y:50, width:50, height:50)
                circle(cx:50, cy:50, r:50)
            }
        }
        __use("xlink:href":"#shape", x:50,  y:50)
    }