user1731504
user1731504

Reputation: 159

create repeated elements based on the field value in xslt

The below is the input xml that has reasoncase element which is repeating.If code under reasonCase is having the value starts with Applicant then create applicant.

<input>
    <case>
        <reasonCase>
            <code>Applicant#1234</code>
            <key>asd345</key>
        </reasonCase>
        <reasonCase>
            <code>Applicant#1234</code>
            <key>asd34567</key>
        </reasonCase>
        <reasonCase>
            <code>Applicant#3456</code>
            <key>asd1111</key>
        </reasonCase>
        <reasonCase>
            <code>Applicant#7889</code>
            <key>asd9999</key>
        </reasonCase>
    </case>
</input>

Expected output is code under reasonCase with same value should be in same applicant element in the output and corresponding elements also should be in the same applicant element

<output>
        <case>
            <applicant>
                <objectid>1234</objectid>
                <reason>
                    <key>asd345</key>
                </reason>
                <reason>
                    <key>asd34567</key>
                </reason>
            </applicant>
            <applicant>
                <objectid>3456</objectid>
                <reason>
                    <key>asd1111</key>
                </reason>
            </applicant>
            <applicant>
                <objectid>7889</objectid>
                <reason>
                    <key>asd9999</key>
                </reason>
            </applicant>
        </case>
    </output>

Based on the reasonCase/code = start-with(Applicant) have to create the repeated elements applicant and corresponding elements.
Please find the below xslt that I tried

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml"/>
        <xsl:template match="/">
            <output>
                <xsl:for-each select="/input/case/reasonCase">
                    <xsl:variable name="code">
                        <xsl:value-of select="./code"/>
                    </xsl:variable>
                    <xsl:choose>
                        <xsl:when test="starts-with(./code,'Applicant')">
                            <Applicants>
                                <objectId>
                                    <xsl:value-of select="substring-after(/*/*/*[code=$code]/code,'Applicant#')"/>
                                </objectId>
                                <reason>
                                    <key><xsl:value-of select="/*/*/*[code=$code]/key"/></key>
                                </reason>
                            </Applicants>
                        </xsl:when>
                    </xsl:choose>
                </xsl:for-each>
            </output>
        </xsl:template>
    </xsl:stylesheet>

The output that I got is as below

<output>
    <Applicants>
        <objectId>1234</objectId>
        <reason>
            <key>asd345</key>
        </reason>
    </Applicants>
    <Applicants>
        <objectId>1234</objectId>
        <reason>
            <key>asd345</key>
        </reason>
    </Applicants>
    <Applicants>
        <objectId>3456</objectId>
        <reason>
            <key>asd1111</key>
        </reason>
    </Applicants>
    <Applicants>
        <objectId>7889</objectId>
        <reason>
            <key>asd9999</key>
        </reason>
    </Applicants>
</output>

Please help me in order to get the expected output.

Upvotes: 0

Views: 893

Answers (2)

Rupesh_Kr
Rupesh_Kr

Reputation: 3445

For Xsl 1.0 you can use

<xsl:template match="input">
<output>
    <case>
        <xsl:for-each select="//code[.!=preceding::code or not(preceding::code)]">
            <xsl:variable name="code" select="text()"/>
            <Applicants>
                <objectid><xsl:value-of select="substring-after(text(), '#')"/></objectid>
                <xsl:for-each select="//key[preceding-sibling::code = $code]">
                    <reason>
                        <xsl:copy-of select="."/>
                    </reason>
                </xsl:for-each>
            </Applicants>
        </xsl:for-each>
    </case>
</output>

and output for this is

    <?xml version="1.0" encoding="UTF-8"?>
<output>
   <case>
      <Applicants>
         <objectid>1234</objectid>
         <reason>
            <key>asd345</key>
         </reason>
         <reason>
            <key>asd34567</key>
         </reason>
      </Applicants>
      <Applicants>
         <objectid>3456</objectid>
         <reason>
            <key>asd1111</key>
         </reason>
      </Applicants>
      <Applicants>
         <objectid>7889</objectid>
         <reason>
            <key>asd9999</key>
         </reason>
      </Applicants>
   </case>
</output>

Upvotes: 1

Rupesh_Kr
Rupesh_Kr

Reputation: 3445

xslt for this issue

<xsl:template match="input">
    <output>
        <case>
            <xsl:for-each-group select="//code" group-by="text()">
                <xsl:variable name="code" select="text()"/>
                <applicant>
                    <objectid><xsl:value-of select="substring-after(text(), '#')"/></objectid>
                    <xsl:for-each select="//key[preceding-sibling::code = $code]">
                        <reason>
                            <xsl:copy-of select="."/>
                        </reason>
                    </xsl:for-each>
                </applicant>
            </xsl:for-each-group>
        </case>
    </output>
</xsl:template>

and output

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <case>
      <applicant>
         <objectid>1234</objectid>
         <reason>
            <key>asd345</key>
         </reason>
         <reason>
            <key>asd34567</key>
         </reason>
      </applicant>
      <applicant>
         <objectid>3456</objectid>
         <reason>
            <key>asd1111</key>
         </reason>
      </applicant>
      <applicant>
         <objectid>7889</objectid>
         <reason>
            <key>asd9999</key>
         </reason>
      </applicant>
   </case>
</output>

Upvotes: 0

Related Questions