Algrach
Algrach

Reputation: 1

XSLT transformation of xml based on type of element value

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

Answers (2)

Martin Honnen
Martin Honnen

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

Rupesh_Kr
Rupesh_Kr

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

Related Questions