Reputation: 25
I have data coming with delimited in input in following format
A;B;C;D;E;F;G;H;I;J;K
and output should look like
<1>A</1>
<2>B</2>
<3>C</3>
<4>D</4>
<5>E</5>
<6>F</6>
<7>G</7>
<8>H</8>
<9>I</9>
<10>J</10>
<11>K</11>
Above mentioned is the maximum length of this delimited string. Have written an xslt to be able to separate the delimited string and get the desired output using multiple substrings like mentioned below and able to get the output
<xsl:value-of
select="substring-before(substring-after(substring-after(substring-after(string,';'),';'),';'),';')"/>
Problem : Provider is not sending the data all times in format mentioned above which is A;B;C;D;E;F;G;H;I;J;K
.
When there are empty values we assumed it would look like A;B;C;D;;;;;;;
.
However in such cases what we are receiving is A;B;C;D
and no empty delimiters there after.
Provided that our string is fixed length our extraction logic using above before and after works. If the length is not respected we are unable to extract data.
Can some one help with the logic which is independent of length received that is data before first delimiter is always <1> and between 1 and 2 delimiters is <2> and so on.
Upvotes: 1
Views: 41
Reputation: 52888
You could use a recursive template to process the tokens. You can pass in the total quantity so if not all of the tokens are present, an element still gets created.
Example...
XML Input
<doc>
<string>A;B;C;D;E;F;G;H;I;J;K</string>
<string>A;B;C;D</string>
<string>A;B;C;;;;G;H;I;J;K</string>
<string/>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="string">
<xsl:copy>
<xsl:call-template name="process_string"/>
</xsl:copy>
</xsl:template>
<xsl:template name="process_string">
<xsl:param name="str" select="."/>
<xsl:param name="qty" select="11"/>
<xsl:param name="item_cnt" select="1"/>
<xsl:variable name="remaining_qty" select="$qty - 1"/>
<xsl:variable name="item_value" select="normalize-space(
substring-before(concat($str, ';'), ';'))"/>
<xsl:element name="item{$item_cnt}">
<xsl:value-of select="$item_value"/>
</xsl:element>
<xsl:if test="substring-after($str,';') or $remaining_qty > 0">
<xsl:call-template name="process_string">
<xsl:with-param name="str" select="substring-after($str,';')"/>
<xsl:with-param name="qty" select="$remaining_qty"/>
<xsl:with-param name="item_cnt" select="$item_cnt + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Output
<doc>
<string>
<item1>A</item1>
<item2>B</item2>
<item3>C</item3>
<item4>D</item4>
<item5>E</item5>
<item6>F</item6>
<item7>G</item7>
<item8>H</item8>
<item9>I</item9>
<item10>J</item10>
<item11>K</item11>
</string>
<string>
<item1>A</item1>
<item2>B</item2>
<item3>C</item3>
<item4>D</item4>
<item5/>
<item6/>
<item7/>
<item8/>
<item9/>
<item10/>
<item11/>
</string>
<string>
<item1>A</item1>
<item2>B</item2>
<item3>C</item3>
<item4/>
<item5/>
<item6/>
<item7>G</item7>
<item8>H</item8>
<item9>I</item9>
<item10>J</item10>
<item11>K</item11>
</string>
<string>
<item1/>
<item2/>
<item3/>
<item4/>
<item5/>
<item6/>
<item7/>
<item8/>
<item9/>
<item10/>
<item11/>
</string>
</doc>
Fiddle: http://xsltfiddle.liberty-development.net/93dFK9i/1
Upvotes: 1