Home > OS >  XLST - How to create "ListOf" xml element with their child?
XLST - How to create "ListOf" xml element with their child?

Time:09-29

I had to learn how to use the XLST to transform the XMLs resulted from JSON->XML transformation.

But, I have the following doubt that I don't know yet how to proceed.

For example, I have the following XML resulted from a JSON->XML transformation:

<User>
    <FirstName>John</FirstName>
    <LastName>Cena</LastName>
    <BirthDate>09/07/1982</BirthDate>
    <Gender>Male</Gender>
    <?xml-multiple hobbies?>
    <hobbies>
        <Description>Watch TV</Description>
    </hobbies>
    <hobbies>
        <Description>Play Games</Description>
    </hobbies>
    <hobbies>
        <Description>Listen to music</Description>
    </hobbies>
</User>

But, the server that I will redirect the data requires the following format when sending lists:

<UpsertUser_Input>
    <data:User>
        <data:FirstName>John</data:FirstName>
        <data:LastName>Cena</data:LastName>
        <data:BirthDate>09/07/1982</data:BirthDate>
        <data:Gender>Male</data:Gender>
        <data:ListOfHobby>    
            <data:Hobby>
                <data:Description>Watch TV</data:Description>
            </data:Hobby>
            <data:Hobby>
                <data:Description>Play Games</data:Description>
            </data:Hobby>
            <data:Hobby>
                <data:Description>Listen to Music</data:Description>
            </data:Hobby>
        </data:ListOfHobby>
    </data:User>
</UpsertUser_Input>

So, to try to do that, I created the following XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:data="http://www.myserver.com/mycom/comUpsertUser/Data">
        <xsl:output indent="yes" omit-xml-declaration="yes" method="xml"/>

        <xsl:template match="/">                        
            <xsl:element name="UpsertUser_Input">
                <xsl:apply-templates select="/User" />
            </xsl:element>
        </xsl:template>

        <xsl:template match="/User">
            <xsl:element name="data:{name()}" >
                <xsl:for-each select="/User/*">
                    <xsl:element name="data:{name()}" >
                        <xsl:value-of select="." />
                    </xsl:element>
                </xsl:for-each>
            </xsl:element>
        </xsl:template>
</xsl:stylesheet>

It works correctly when creating the non-list fields.

But I didn't figured out a better way to create the "ListOfxxx" with the "xxx" inside of it. It creates, obviously, the following:

<data:hobbies>Watch TV</data:hobbies>
<data:hobbies>Play Games</data:hobbies>
<data:hobbies>Listen to music</data:hobbies>

I tought about using the <xsl:choose> to check name()='hobbies'but I'm not sure if it will work the way that it must.

Please, when possible, could you give a light or suggest a way of doing this?

Thanks in advance!

CodePudding user response:

How about:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:data="http://www.myserver.com/mycom/comUpsertUser/Data">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/User">
    <UpsertUser_Input>
        <data:User>
            <xsl:apply-templates select="*[not(self::hobbies)]"/>
            <data:ListOfHobby>  
                <xsl:apply-templates select="hobbies"/>
            </data:ListOfHobby>   
        </data:User>
    </UpsertUser_Input>
</xsl:template>
 
<xsl:template match="*">
     <xsl:element name="data:{name()}" >
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

<xsl:template match="hobbies">
    <data:Hobby>
        <xsl:apply-templates/>
    </data:Hobby>   
</xsl:template>

</xsl:stylesheet>
  • Related