0
votes

I would like to know the better approach to solve this solution in xslt 2.0.

Input:

<Root>
    <Record>
        <FName>Abc</FName>
        <MName>FAbc</MName>
        <Kid>
            <CName>C1Abc<CName>
        </Kid>
        <Kid>
            <CName>C2Abc<CName>
        </Kid>
    </Record>
    <Record>
        <FName>Def</FName>
        <MName>FDef</MName>
        <Kid>
            <CName>C1Def<CName>
        </Kid>
    </Record>
    <Record>
        <FName>Xyz</FName>
        <MName>FXyz</MName>
    </Record>
</Root>

Output:

<Root>
    <Record>
        <FName>Abc</FName>
        <MName>FAbc</MName>
        <CName>C1Abc<CName>
    </Record>
    <Record>
        <FName>Abc</FName>
        <MName>FAbc</MName>
        <CName>C2Abc<CName>
    </Record>
    <Record>
        <FName>Def</FName>
        <MName>FDef</MName>
        <CName>C1Def<CName>
    </Record>
    <Record>
        <FName>Xyz</FName>
        <MName>FXyz</MName>
        <CName></CName>
    </Record>
</Root>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="2.0">

    <xsl:template match="Root">
        <Root>
            <xsl:apply-templates select="Record">
            </xsl:apply-templates>
        </Root>
    </xsl:template>

    <xsl:template match="Record">
        <xsl:choose>
            <xsl:when test="Kid">
                <xsl:apply-templates select="Kid">                              
                </xsl:apply-templates>  
            </xsl:when>
            <xsl:otherwise>
                <Record>   
                    <FName>
                        <xsl:value-of select="FName"/>
                    </FName>
                    <MName>
                        <xsl:value-of select="MName"/>
                    </MName>        
                    <CName>
                        <xsl:value-of select="Kid/CName"/>
                    </CName>
                </Record>                                   
            </xsl:otherwise>
        </xsl:choose>       
    </xsl:template>

    <xsl:template match="Kid">  
        <Record>   
            <FName>
                <xsl:value-of select="../FName"/>
            </FName>
            <MName>
                <xsl:value-of select="../MName"/>
            </MName>
            <CName> 
                <xsl:value-of select="CName"/>
            </CName>            
        </Record>               
    </xsl:template>
</xsl:stylesheet>

My xslt works and I am able to get the output what I expect. But I would like to hear if there any other better approach to do this. Mainly to avoid any performance issues as there will be thousands of records with much more data. Thank you.

1
Will there always be an FName and MName always be present? Or can any of the child elements be optional?Tim C
Do you actually have performance problems? Have you profiled your existing code with your XSLT processor to find out which code needs to be improved?Martin Honnen
@Tim C, all the child elements are optional but there should be an empty tag <FName /> and <MName /> if there is no value.user3836593
@MartinHonnen, not really did those performance testing. I am quite new to writing xslt and I am more like to learn any eventual stupidity I have made in my xslt.user3836593

1 Answers

0
votes

You could rewrite

<xsl:template match="Record">
    <xsl:choose>
        <xsl:when test="Kid">
            <xsl:apply-templates select="Kid">                              
            </xsl:apply-templates>  
        </xsl:when>
        <xsl:otherwise>
            <Record>   
                <FName>
                    <xsl:value-of select="FName"/>
                </FName>
                <MName>
                    <xsl:value-of select="MName"/>
                </MName>        
                <CName>
                    <xsl:value-of select="Kid/CName"/>
                </CName>
            </Record>                                   
        </xsl:otherwise>
    </xsl:choose>       
</xsl:template>

as

<xsl:template match="Record[not(Kid)]">
            <Record>   
                <FName>
                    <xsl:value-of select="FName"/>
                </FName>
                <MName>
                    <xsl:value-of select="MName"/>
                </MName>        
                <CName></CName>
            </Record>                                       
</xsl:template>

<xsl:template match="Record[Kid]">
  <xsl:apply-templates select="Kid"/>
</xsl:template>