0
votes

I am new to XSLT, cant get my head around it. Need to transform the below input file to below output file, can someone help me with xslt code. thanks in advance. inputFile:

  <input>
    <inputOne>
        <numberOne>1</numberOne>
    </inputOne>
    <inputTwo>
        <numberTwo>2</numberTwo>
    </inputTwo>
    <inputThree>
        <numberThree>3</numberThree>
    </inputThree>
    <inputFive>
        <numberFive>5</numberFive>
    </inputFive>
    <inputFour>
        <numberFour>4</numberFour>
    </inputFour>
    <inputThree>
        <numberThree>32</numberThree>
    </inputThree>
    <inputFive>
        <numberFive>52</numberFive>
    </inputFive>
    <inputFour>
        <numberFour>42</numberFour>
    </inputFour>
</input>

outputFile:

<input>
    <inputOne>
        <numberOne>1</numberOne>
        <inputTwo>
            <numberTwo>2</numberTwo>
            
            <inputThree>
                <numberThree>3</numberThree>
                <inputFour>
                    <numberFour>4</numberFour>
                    <inputFive>
                        <numberFive>5</numberFive>
                    </inputFive>
                </inputFour>
            </inputThree>
            
            <inputThree>
                <numberThree>32</numberThree>
                <inputFour>
                    <numberFour>42</numberFour>
                    <inputFive>
                        <numberFive>52</numberFive>
                    </inputFive>
                </inputFour>
            </inputThree>
            
        </inputTwo>
    </inputOne>
</input>

I am using Transformer object to transform streamsource into streamresult object. the transform object is created using xsl file.

my xsl file is not working.

xslcode:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8"/>
    <xsl:template match="/input">
        <xsl:copy>
            <xsl:apply-templates select="inputOne"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="inputOne">
        <xsl:apply-templates select="inputTwo"/>
    </xsl:template>
    <xsl:template match="inputOne[not(inputTwo)]">
        <xsl:copy-of select="."/>
    </xsl:template>
    <xsl:template match="inputTwo">
        <xsl:copy-of select="."/>
    </xsl:template>
</xsl:stylesheet>

with above xsl i am trying to get inputOne tag and inside it inputTwo tag. but just getting the below:

<input>
<inputOne>
        <numberOne>1</numberOne>
    </inputOne>
    
</input>

appreciate any help to fix the xsl code. Thanks.

1
The input XML has a very questionable structure. - Yitzhak Khabinsky
agree. but that's the task. - sachin
Please explain the logic that needs to be applied here. - michael.hor257k
the logic probably does not seem obvious in the question, as I have to change tag and element names. As I cannot post them as it is. But the requirement should be obvious. inputOne is the parent of inputTwo and they do not repeat. file level tags. inputThree is a child of inpuTwo and inputFour is of inputThree and inputFour is of InputFive. tags InputThree through inputFive repeat. the file coming in needs to be transformed as the outputfile with the parent-child relationship defined here. Thanks - sachin
It is not obvious at all which inputThree is the parent of which inputFour etc. I could understand it if each level would look only at its following siblings that do not have a closer preceding sibling at the same level. But you have inputFive before inputFour - and I don't know how to formulate a rule for that. - michael.hor257k

1 Answers

0
votes

FWIW, the following stylesheet will generate, with a lot of effort, the result shown in your question. Whether the logic implemented here will suit all your possible inputs is not clear to me.

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" oversion="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="in4" match="inputFour" use="generate-id(preceding-sibling::inputThree[1])" />
<xsl:key name="in5" match="inputFive" use="generate-id(following-sibling::inputFour[1])" />

<xsl:template match="/input">
    <xsl:copy>
        <xsl:apply-templates select="inputOne"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="inputOne">
    <xsl:copy>
        <xsl:copy-of select="numberOne"/>
        <xsl:apply-templates select="../inputTwo"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="inputTwo">
    <xsl:copy>
        <xsl:copy-of select="numberTwo"/>
        <xsl:apply-templates select="../inputThree"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="inputThree">
    <xsl:copy>
        <xsl:copy-of select="numberThree"/>
        <xsl:apply-templates select="key('in4', generate-id())"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="inputFour">
    <xsl:copy>
        <xsl:copy-of select="numberFour"/>
        <xsl:apply-templates select="key('in5', generate-id())"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="inputFive">
    <xsl:copy>
        <xsl:copy-of select="numberFive"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>