Search code examples
groovy

How to create multiple root nodes based on the occurrence of a child node


Create multiple CompoundEmployee nodes based on the occurrence on no of employment_information nodes keeping the parent nodes intact

Input:
queryCompoundEmployeeResponse
CompoundEmployee
person
personal_information
email_information
employment_information
employment_information
CompoundEmployee
person
personal_information
email_information
employment_information

Output:

queryCompoundEmployeeResponse
CompoundEmployee
person
personal_information
email_information
employment_information
CompoundEmployee
person
personal_information
email_information
employment_information
CompoundEmployee
person
personal_information
email_information
employment_information
import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil

def xml = '''
<?xml version="1.0" encoding="UTF-8"?>
<queryCompoundEmployeeResponse>
    <CompoundEmployee>
        <id>Dummy1</id>
        <person>
            <person_id_external>Dummy1</person_id_external>
            <personal_information>
                <first_name>Test01</first_name>
                <gender>M</gender>
                <last_name>test01</last_name>
            </personal_information>
            <employment_information>
                <isContingentWorker>false</isContingentWorker>
                <jobNumber>1</jobNumber>
                <start_date>2019-04-01</start_date>
                <job_information>
                    <company>LE-USA-001</company>
                </job_information>
            </employment_information>
            <employment_information>
                <isContingentWorker>false</isContingentWorker>
                <jobNumber>2</jobNumber>
                <start_date>2019-04-01</start_date>
                <job_information>
                    <company>LE-USA-004</company>
                </job_information>
            </employment_information>
        </person>
    </CompoundEmployee>
    <CompoundEmployee>
        <id>Dummy2</id>
        <person>
            <person_id_external>Dummy2</person_id_external>
            <personal_information>
                <first_name>Test02</first_name>
                <gender>M</gender>
                <last_name>test02</last_name>
            </personal_information>
            <employment_information>
                <isContingentWorker>true</isContingentWorker>
                <jobNumber>3</jobNumber>
                <job_information>
                    <company>LE-BRA-001</company>
                </job_information>
            </employment_information>
        </person>
    </CompoundEmployee>
</queryCompoundEmployeeResponse>
'''

def root = new XmlParser().parseText(xml)
def newXml = new StreamingMarkupBuilder().bind {

    queryCompoundEmployeeResponse{
        root.CompoundEmployee.each { compoundEmployee ->
            compoundEmployee.person.employment_information.each { employmentInfo ->
                CompoundEmployee{
                    id(compoundEmployee.id)
                    person{
                        person_id_external(compoundEmployee.person.person_id_external)
                        personal_information(compoundEmployee.person.personal_information)
                        email_information(compoundEmployee.person.email_information)
                        employment_information(employmentInfo)
                    }
                }
            }
        }
    }

}
println XmlUtil.serialize(newXml)

Output:

<queryCompoundEmployeeResponse>
    <CompoundEmployee>
        <id>id[attributes={}; value=[Dummy1]]</id>
        <person>
            <person_id_external>person_id_external[attributes={}; value=[Dummy1]]</person_id_external>
            <personal_information>personal_information[attributes={}; value=[first_name[attributes={}; value=[Test01]], gender[attributes={}; value=[M]], last_name[attributes={}; value=[test01]]]]</personal_information>
            <email_information>email_information[attributes={}; value=[email_address[attributes={}; value=[[email protected]]], email_type[attributes={}; value=[B]], isPrimary[attributes={}; value=[true]]]]</email_information>
            <employment_information>isContingentWorker[attributes={}; value=[false]]jobNumber[attributes={}; value=[1]]start_date[attributes={}; value=[2019-04-01]]job_information[attributes={}; value=[company[attributes={}; value=[LE-USA-001]], start_date[attributes={}; value=[2020-04-24]]]]job_information[attributes={}; value=[company[attributes={}; value=[LE-USA-002]], start_date[attributes={}; value=[2020-04-23]]]]</employment_information>
        </person>
    </CompoundEmployee>
    <CompoundEmployee>
        <id>id[attributes={}; value=[Dummy1]]</id>
        <person>
            <person_id_external>person_id_external[attributes={}; value=[Dummy1]]</person_id_external>
            <personal_information>personal_information[attributes={}; value=[first_name[attributes={}; value=[Test01]], gender[attributes={}; value=[M]], last_name[attributes={}; value=[test01]]]]</personal_information>
            <email_information>email_information[attributes={}; value=[email_address[attributes={}; value=[[email protected]]], email_type[attributes={}; value=[B]], isPrimary[attributes={}; value=[true]]]]</email_information>
            <employment_information>isContingentWorker[attributes={}; value=[false]]jobNumber[attributes={}; value=[2]]start_date[attributes={}; value=[2019-04-01]]job_information[attributes={}; value=[company[attributes={}; value=[LE-USA-004]], start_date[attributes={}; value=[2020-04-24]]]]</employment_information>
        </person>
    </CompoundEmployee>
    <CompoundEmployee>
        <id>id[attributes={}; value=[Dummy2]]</id>
        <person>
            <person_id_external>person_id_external[attributes={}; value=[Dummy2]]</person_id_external>
            <personal_information>personal_information[attributes={}; value=[first_name[attributes={}; value=[Test02]], gender[attributes={}; value=[M]], last_name[attributes={}; value=[test02]]]]</personal_information>
            <email_information>email_information[attributes={}; value=[email_address[attributes={}; value=[[email protected]]], email_type[attributes={}; value=[B]], isPrimary[attributes={}; value=[true]]]]</email_information>
            <employment_information>isContingentWorker[attributes={}; value=[true]]jobNumber[attributes={}; value=[3]]job_information[attributes={}; value=[company[attributes={}; value=[LE-BRA-001]], start_date[attributes={}; value=[2020-04-24]]]]</employment_information>
        </person>
    </CompoundEmployee>
</queryCompoundEmployeeResponse>

Issue: The output xml contains nodes personal_information,email_information,employment_information that have values as Node type, need to convert into xml as in the Input eg.

<personal_information>
personal_information[attributes={}; value=[first_name[attributes={}; value=[Test01]], gender[attributes={}; value=[M]], last_name[attributes={}; value=[test01]]]]
</personal_information>
  • This needs to be below format in the output:
 <personal_information>
  <first_name>Test01</first_name>
  <gender>M</gender>
  <last_name>test01</last_name>
  </personal_information>

Please can you correct me what I am doing wrong here? Note: The schema is very big and contains multiple fields. I have just made a simple schema. Code needs to dynamically generate all the fields/elements of that particular node.


Solution

  • use XmlSlurper

    def root = new XmlSlurper().parseText(xml)
    

    then this mkp.yeld should work

    person{
        person_id_external(compoundEmployee.person.person_id_external)
        mkp.yield compoundEmployee.person.personal_information
        email_information(compoundEmployee.person.email_information)
        employment_information(employmentInfo)
    }