You can use just the each
method on lists. You have to take care on the following: every matched method call inside the builder.bind
will call the respective method/variable; thus you will need different names. That's even better, because you don't make ambiguous naming. You can just structure the whole XML inside the eachs
. It's a somewhat large, but this fills your XML the way you want:
UPDATE:
Since your model is reversed, i made the following:
// definition of the model and mock data
@Canonical class Prescription {
int id
String prescriptionType, duration, drugName, route
int refills
Clinic clinic
Patient patient
}
@Canonical class Clinic {
int id
String name
}
@Canonical class Patient {
int id
String firstName, lastName
}
def patient2 = new Patient(2, "John", "Doe")
def patient4 = new Patient(4, "Sylvia", "Plath")
def clinic1 = new Clinic(1, "Clinic 1")
def clinic2 = new Clinic(2, "Clinic 2")
def prescriptions = [
new Prescription(2, "Formulary", "duration", "Lipitor", "route", 5, clinic1, patient2),
new Prescription(4, null, null, "Tums", null, 0, clinic2, patient2),
new Prescription(5, null, null, "BandAids", null, 5, clinic2, patient4)
]
The best bet is to reverse the model so it matches the XML structure. You can easily reverse it using this snippet:
clins = prescriptions.inject([:].withDefault({ [:] })) { map, pres ->
map[ pres.clinic ] << [ (pres.patient) : pres ]
map
}
Now you build the XML according to the map structure:
builder = new groovy.xml.StreamingMarkupBuilder()
xml = builder.bind {
clinics {
clins.each { cliEntry -> cli = cliEntry.key
clinic(id: cli.id, name: cli.name) {
cliEntry.value.each { patEntry -> pat = patEntry.key
patient(id: pat.id, firstName: pat.firstName, lastName: pat.lastName){
patEntry.value.each { pres ->
prescription(id: pres.id) {
prescriptionType pres.prescriptionType
duration pres.duration
drugName pres.drugName
route pres.route
refills pres.refills
}
}
}
}
}
}
}
}
And the test:
assert xml.toString() == """<clinics><clinic id='1' name='Clinic 1'><patient id='2' firstName='John' lastName='Doe'><prescription id='2'><prescriptionType>Formulary</prescriptionType><duration>duration</duration><drugName>Lipitor</drugName><route>route</route><refills>5</refills></prescription></patient></clinic><clinic id='2' name='Clinic 2'><patient id='2' firstName='John' lastName='Doe'><prescription id='4'><prescriptionType/><duration/><drugName>Tums</drugName><route/><refills>0</refills></prescription></patient><patient id='4' firstName='Sylvia' lastName='Plath'><prescription id='4'><prescriptionType/><duration/><drugName>Tums</drugName><route/><refills>0</refills></prescription></patient></clinic></clinics>"""