Pablo Pazos
Pablo Pazos

Reputation: 3216

How to customize the root element name for an object XML marshaller in Grails

I'm using Grails 2.5.3 and have a domain class Person.

I created an XML marshaller of Person, and it creats an XML with "person" as the root element name. Depending on the role of the person I would like to name the root element "patient" or "doctor", but there is no documentation in Grails, nor on implementers web sites about this.

The only thing I could find is how to customize the root element name for collection XML marshallers, like: Grails XML marshalling: change default "<list>" root element name

Is there any way of customizing the root element name for object XML marshallers?

What I have currently is:

XML.registerObjectMarshaller(Person) { person, xml ->
        xml.build {
          uid(person.uid)
          firstName(person.firstName)
          lastName(person.lastName)
          dob(person.dob)
          sex(person.sex)
          idCode(person.idCode)
          idType(person.idType)
          organizationUid(person.organizationUid)
        }
}

Upvotes: 3

Views: 221

Answers (1)

agentscarn
agentscarn

Reputation: 146

The registerObjectMarshaller method that you are using has an overload that takes an ObjectMarshaller instance. To override the name of the root element the marshaller you register needs to also implement the NameAwareMarshaller interface.

The answer in the post you linked handles all of this by registering an object that extends from CollectionMarshaller which is an implementer of both ObjectMarshaller and NameAwareMarshaller.

To customize the root element name the way you would like, you would need to create a class that implements ObjectMarshaller and NameAwareMarshaller. Your usage of registerObjectMarshaller method is passing a closure which is being used by ObjectMarshaller.marshallObject(...). You can use the body of the closure in your new class's implementation of the marshalObject method.

class PersonMarshaller implements ObjectMarshaller<XML>, NameAwareMarshaller {

    boolean supports(Object object) {
        return object instanceof Person;
    }

    String getElementName(Object o) {
        if (object instanceof Patient) {
            return "patient";
        } else if (object instanceof Doctor) {
            return "doctor";
        } else {
            return "patient";
        }
    }

    void marshalObject(Object object, XML xml) {
        Person person = (Person) object;

        xml.build {
          uid(person.uid)
          firstName(person.firstName)
          lastName(person.lastName)
          dob(person.dob)
          sex(person.sex)
          idCode(person.idCode)
          idType(person.idType)
          organizationUid(person.organizationUid)
        }
    }
}

Upvotes: 3

Related Questions