Padd T
Padd T

Reputation: 65

XSLT Split into separate segments based on key field value

i am trying to write XSLT mapping to create separate Instruction segment based on sub segment Instructiontext, whenever there is key word called /NEW LINE/ is present in the InstructionText segment. I have written a code but its giving error, Please help me on this..

i attached sample input and output as below. Please check.

Input:

<?xml version="1.0" encoding="UTF-8"?>
<TIM>
    <SBDH>
        <FIELD1>132</FIELD1>
    </SBDH>
    <TI>
        
        <TIC>           
            <Instruction>
                <InstructionText languageCode="EN">20</InstructionText>
            </Instruction>
            <Instruction>
                <InstructionText languageCode="EN">234</InstructionText>
            </Instruction>
            <Instruction>
                <InstructionText languageCode="EN">456 /NEW LINE/ 789 /NEW LINE/ 910/NEW LINE/</InstructionText>
            </Instruction>
            
        </TIC>
    </TI>
</TIM>

** Desired Output:**

<?xml version="1.0" encoding="UTF-8"?>
<TIM>
    <SBDH>
        <FIELD1>132</FIELD1>
    </SBDH>
    <TI>
        <TIC>
            <Instruction>
                <InstructionText languageCode="EN">20</InstructionText>
            </Instruction>
            <Instruction>
                <InstructionText languageCode="EN">234</InstructionText>
            </Instruction>
            <Instruction>
                <InstructionText languageCode="EN">456</InstructionText>
            </Instruction>
            <Instruction>
                <InstructionText languageCode="EN">789</InstructionText>
            </Instruction>
            <Instruction>
                <InstructionText languageCode="EN">910</InstructionText>
            </Instruction>
        </TIC>
    </TI>
</TIM>

** XSLT I used is below:**

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    <xsl:template match="/">
       
            <xsl:for-each select="//InstructionText">
            
                <xsl:for-each select="tokenize(string(InstructionText), '/NEW LINE/')">
                    <InstructionText>
                        <InstructionText><xsl:value-of select="."/></InstructionText>
                      
                     </InstructionText>
                </xsl:for-each>
            </xsl:for-each>
      
    </xsl:template>
</xsl:stylesheet>   

Please assist here.

Upvotes: 0

Views: 82

Answers (1)

y.arazim
y.arazim

Reputation: 3250

If your processor supports XSLT 3.0, you should be able to do something like:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="Instruction"> 
      <xsl:apply-templates/>
</xsl:template>

<xsl:template match="InstructionText">
    <xsl:variable name="languageCode" select="@languageCode" />       
    <xsl:for-each select="tokenize(., '/NEW LINE/')[normalize-space(.)]">
        <Instruction>
            <InstructionText languageCode="{$languageCode}">
                <xsl:value-of select="normalize-space(.)"/>
            </InstructionText>
        </Instruction>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>  

You can see it working here.

Upvotes: 1

Related Questions