kkalaany
-
Posts
2 -
Joined
-
Last visited
Content Type
Profiles
Forums
Events
Posts posted by kkalaany
-
-
I'm trying to split the elements into new elements, from this format :
<CTP> <name>ABSA bank</name> <BAs.BA>bank|sector|issuer</BAs.BA> <altIDs.altID.label_altSystem>ABSB_BBG|ASB_Reuters</altIDs.altID.label_altSystem> </CTP>
to this format:<CTP> <name>ABSA bank</name> <BAs> <BA>bank</BA> <BA>sector</BA> <BA>issuer</BA> </BAs> <altIDs> <aldID> <label>ABSB</label> <altSystem>BBG</altSystem> </aldID> <aldID> <label>ASB</label> <altSystem>Reuters</altSystem> </aldID> </altIDs> </CTP>
What I did so far is to transform this format:<CTP> <name>ABSA bank</name> <BAs.BA>bank|sector|issuer</BAs.BA> <FAs.FA.F>dep|sec|issue</FAs.FA.F> </CTP>
to this formmat :
<?xml version="1.0" encoding="UTF-8"?> <CTP> <name>ABSA bank</name> <BAs> <BA>bank</BA> <BA>sector</BA> <BA>issuer</BA> </BAs> <FAs> <FA> <F>dep</F> <F>sec</F> <F>issue</F> </FA> </FAs> </CTP>
Using this Code with the help of @michael.hor257k<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="*[contains(name(), '.')]" name="nest"> <xsl:param name="name" select="name()"/> <xsl:param name="delimiter" select="'.'"/> <xsl:choose> <xsl:when test="contains($name, $delimiter)"> <xsl:element name="{substring-before($name, $delimiter)}" > <!-- recursive call --> <xsl:call-template name="nest"> <xsl:with-param name="name" select="substring-after($name, $delimiter)"/> </xsl:call-template> </xsl:element> </xsl:when> <xsl:otherwise> <xsl:call-template name="tokenize"> <xsl:with-param name="name" select="$name"/> <xsl:with-param name="text" select="."/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="tokenize"> <xsl:param name="name"/> <xsl:param name="text"/> <xsl:param name="delimiter" select="'|'"/> <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" /> <xsl:if test="$token"> <xsl:element name="{$name}" > <xsl:value-of select="$token"/> </xsl:element> </xsl:if> <xsl:if test="contains($text, $delimiter)"> <!-- recursive call --> <xsl:call-template name="tokenize"> <xsl:with-param name="name" select="$name"/> <xsl:with-param name="text" select="substring-after($text, $delimiter)"/> </xsl:call-template> </xsl:if> </xsl:template> </xsl:stylesheet>
The tricky step that I need is how to use many delimiters and access layers and levels to write the needed XML format.
split XML element into new elements
in XSLT/XSL-FO
Posted · Edited by kkalaany
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[contains(name(), '_')]" name="nest">
<xsl:param name="name" select="name()" />
<xsl:param name="delimiter" select="'_'" />
<xsl:param name="text" select="." />
<xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
<xsl:choose>
<xsl:when test="contains($name, $delimiter)">
<xsl:element name="{substring-before($name, $delimiter)}">
<xsl:value-of select="$token" />
</xsl:element>
<xsl:element name="{substring-after($name, $delimiter)}">
<xsl:variable name="token" select="substring-after($text, $delimiter)" />
<xsl:value-of select="$token" />
<!-- recursive call -->
<xsl:call-template name="nest">
<xsl:with-param name="name" select="substring-after($name, $delimiter)" />
<xsl:with-param name="text" select="substring-after($text, $delimiter)" />
</xsl:call-template>
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>