Reputation: 1
I want to create XSLT schema to transform my xml record. Here is an example of incoming xml
<Target>
<name1>AMRXQUAL</name1>
<name2>0</name2>
<name3>217</name3>
<name4>72</name4>
</Target>
This is expected output after xslt transformation :
<Target>
<string_fields>
<name1>AMRXQUAL</name1>
</string_fields>
<int_fields>
<name2>0</name2>
<name3>217</name3>
<name4>72</name4>
</int_fields>
</Target>
The idea is to check type of each element in Target and then move it to corresponding element on root level. If element type is integer we move it to int_fields, if element is string - we move it to string_fields and so on . Thank you in advance !
Upvotes: 0
Views: 86
Reputation: 167436
With castable as
you could check the type and then write a function returning your desired type prefix and use it in group-by:
<xsl:function name="mf:get-type" as="xs:string">
<xsl:param name="input"/>
<xsl:sequence
select="if ($input castable as xs:integer)
then 'int'
else if ($input castable as xs:decimal)
then 'dec'
else if ($input castable as xs:boolean)
then 'boolean'
else 'string'"/>
</xsl:function>
<xsl:template match="Target">
<xsl:copy>
<xsl:for-each-group select="*" group-by="mf:get-type(.)">
<xsl:element name="{current-grouping-key()}_fields">
<xsl:copy-of select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
Upvotes: 1
Reputation: 3435
Try this
<xsl:template match="Target">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="substring(local-name(), 1, 1)">
<xsl:choose>
<xsl:when test="current-grouping-key() = 's'">
<string_fields>
<xsl:apply-templates select="current-group()"/>
</string_fields>
</xsl:when>
<xsl:when test="current-grouping-key() = 'i'">
<int_fields>
<xsl:apply-templates select="current-group()"/>
</int_fields>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
See Transformation at https://xsltfiddle.liberty-development.net/6q1SDjN
Upvotes: 0