Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: fixed the link to the astronomical example

...

Here's an example:

Code Block

def f = frame(size:[300,300], text:'My Window') {
    label(bounds:[10,10,290,30], text:'Save changes')
    panel(bounds:[10,40,290,290]) {
        button(text:'OK', action:{ save close })
        button(text:'Cancel', action:{ close })
    }
}

...

Note that within the 'markup' you can embed normal expressions - i.e. this markup syntax is a normal part of the Groovy language. e.g.

Code Block

def f = frame(text: calculateFieldNamefoo, 1234){

    // lets iterate through some map
    map = [1:"hello", 2:"there"]

    for e in map {
      labelname:e.value
      textfieldname:e.value
    }
}

...

Here's an example of some HTML using some mixed content which is typically hard to do neatly in some markup languages

Code Block

html {
    head {
        title"XML encoding with Groovy"
    }
    body {
        h1"XML encoding with Groovy"
        p"this format can be used as an alternative markup to XML"

        / an element with attributes and text content /
        ahref:'http://groovy.codehaus.org' ["Groovy"]

        / mixed content /
        p [
            "This is some",
            b"mixed",
            "text. For more see the",
            ahref:'http://groovy.codehaus.org' ["Groovy"],
            "project"
        ]
        p "some text"
    }
}

Finally here's an example of creating some name-spaced XML structure XSD...

Code Block

def builder = NodeBuilder.newInstance()
def xmlns = new groovy.xml.NamespaceBuilder(builder)

def xsd = xmlns.namespace('http://www.w3.org/2001/XMLSchema', 'xsd')

def root = xsd.schema(xmlns:['foo':'http://someOtherNamespace']) {
  annotation {
      documentation("Purchase order schema for Example.com.")
      //documentation(xmlns=[xml.lang:'en']) ["Purchase order schema for Example.com."]
  }
  element(name:'purchaseOrder', type:'PurchaseOrderType')
  element(name:'comment', type:'xsd:string')
  complexType(name:'PurchaseOrderType') {
    sequence {
      element(name:'shipTo', type:'USAddress')
      element(name:'billTo', type:'USAddress')
      element(minOccurs:'0', ref:'comment')
      element(name:'items', type:'Items')
    }
    attribute(name:'orderDate', type:'xsd:date')
  }
  complexType(name:'USAddress') {
    sequence {
      element(name:'name', type:'xsd:string')
      element(name:'street', type:'xsd:string')
      element(name:'city', type:'xsd:string')
      element(name:'state', type:'xsd:string')
      element(name:'zip', type:'xsd:decimal')
    }
    attribute(fixed:'US', name:'country', type:'xsd:NMTOKEN')
  }
  complexType(name:'Items') {
    sequence {
      element(maxOccurs:'unbounded', minOccurs:'0', name:'item') {
        complexType {
          sequence {
            element(name:'productName', type:'xsd:string')
            element(name:'quantity') {
              simpleType {
                restriction(base:'xsd:positiveInteger') {
                  maxExclusive(value:'100')
                }
              }
            }
            element(name:'USPrice', type:'xsd:decimal')
            element(minOccurs:'0', ref:'comment')
            element(minOccurs:'0', name:'shipDate', type:'xsd:date')
          }
          attribute(name:'partNum', type:'SKU', use:'required')
        }
      }
    }
  }
  /* Stock Keeping Unit, a code for identifying products */
  simpleType(name:'SKU') {
    restriction(base:'xsd:string') {
      pattern(value:'\\d{3}-[A-Z]{2}')
    }
  }
}

...

To output elements or attributes with a '-' in their name, you need to quote the names. For example, to generate a web-app descriptor for a Servlet app:

Code Block

def builder = new groovy.xml.MarkupBuilder()
builder.'web-app' {
    'display-name' 'My Web Application'
}

generates:

Code Block

<web-app>
  <display-name>My Web Application</display-name>
</web-app>

...

Most builder examples are inline usage. To use a builder to build for an external variable, you may use:

Code Block

class MyConfig{
  static nodes = {
    'first entry'( key: 'value')
  }
}

def result = new YourBuilder().invokeMethod('rootNode', MyConfig.nodes )

...

Andy Glover introduces builders through an astronomical example