xmlgrailsgroovymarshallingmarkupbuilder

XML marshalling of nested elements in Grails using Groovy markup builder syntax


Grails: v2.5.0

How can I generate XML including nested elements without attributes?

This is my desired output:

<?xml version="1.0" encoding="UTF-8"?>
<list>
  <book>
    <title>Title</title>
    <authors>
      <author>
        <fname>First Name</fname>
        <lname>Last Name</lname>
      </author>
    </authors>
  </book>
</list>

Using the following marshaller...

// imports...

class BootStrap {

  def init = { servletContext ->
    XML.registerObjectMarshaller(Book) { Book book, converter ->
      converter.build {
        title book.title
        authors {
          for (a in book.authors) {
            author {
              fname a.fname
              lname a.lname
            }
          }
        }
      }
    }
  }
}

...the authors element is not included in the output:

<?xml version="1.0" encoding="UTF-8"?>
<list>
  <book>
    <title>Title</title>
  </book>
</list>

However, when adding an attribute to both the authors and author elements...

// imports...

class BootStrap {

  def init = { servletContext ->
    XML.registerObjectMarshaller(Book) { Book book, converter ->
      converter.build {
        title book.title
        authors(bla: 'bla') {
          for (a in book.authors) {
            author(bla: 'bla') {
              fname a.fname
              lname a.lname
            }
          }
        }
      }
    }
  }
}

...the elements are included in the output:

<?xml version="1.0" encoding="UTF-8"?>
<list>
  <book>
    <title>Title</title>
    <authors bla="bla">
      <author bla="bla">
        <fname>First Name</fname>
        <lname>Last Name</lname>
      </author>
    </authors>
  </book>
</list>

Can someone point me in the right direction?

Thanks!


Solution

  • Found a solution: add parentheses and an empty list.

    Here's the code:

    // imports...
    
    class BootStrap {
    
      def init = { servletContext ->
        XML.registerObjectMarshaller(Book) { Book book, converter ->
          converter.build {
            title book.title
            authors([]) {
              for (a in book.authors) {
                author([]) {
                  fname a.fname
                  lname a.lname
                }
              }
            }
          }
        }
      }
    }