I need to create/convert a XML structure into another XML structure. This is the response structure i get from the source. The number of "Users" is variable.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<User>
<person>
<person_id>1234</person_id>
</person>
</User>
<User>
<person>
<person_id>5678</person_id>
</person>
</User>
</Response>
The target structure is supposed to look like this:
<?xml version="1.0" encoding="UTF-8"?>
<S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<queryResponse xmlns="urn:test.com" xmlns:ns2="urn:example.com">
<result>
<object>
<id>1234(*person_id from source message*)</id>
<type>Employee</type>
<person>*here the whole person number 1 object from source XML must be inserted*</person>
<execution_timestamp></execution_timestamp>
<version_id></version_id>
</object>
<object>
<id>5678(*person_id from source message*)</id>
<type>Employee</type>
<person>*here the whole person number 2 object from source XML must be inserted*</person>
<execution_timestamp></execution_timestamp>
<version_id></version_id>
</object>
<numResults>*number of Users from source XML must be inserted here(in this case 2)*</numResults>
</result>
</queryResponse>
</S:Body>
This task is extremly complicated and I would be happy if anyone could give me any suggestions. I need to solve this with groovyscript if possible. Otherwise XSLT.
I have tried to create the structure of the target XML as a String and then manually concatenate the "person" objects from the source XML into the structure. But the iteration over the dynamic number of the Users is where I have no idea how to solve it. Especially since it has to be done from certain nodes into certain nodes. I do not know how to dynamically create the number of nodes/objects in the target dependent on the number of "User" nodes in the source.
Thank you in advance.
CodePudding user response:
Using XSLT :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<queryResponse xmlns="urn:test.com" xmlns:ns2="urn:example.com">
<result>
<xsl:for-each select="Response/User">
<object>
<id>
<xsl:value-of select="person/person_id"/>
</id>
<type>Employee</type>
<person>
<xsl:apply-templates select="person/*"/>
</person>
<execution_timestamp></execution_timestamp>
<version_id></version_id>
</object>
</xsl:for-each>
<numResults>
<xsl:value-of select="count(Response/User)"/>
</numResults>
</result>
</queryResponse>
</S:Body>
</xsl:template>
<!-- Modify elements to new namespace. -->
<xsl:template match="*">
<xsl:element name="{local-name(.)}" namespace="urn:test.com">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
You might need to make sure the namespaces are handled properly in your output.
See it working here: https://xsltfiddle.liberty-development.net/948CNrP/4