[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Group Techniques by xslt
Joga Singh Rawat wrote:
If someone have a logic to structure a data of unstructred file, please help. I am clueless. I am new in xslt 2.0. Here is a partial solution: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:mf="http://example.com/2009/mf" exclude-result-prefixes="xsd mf"> <xsl:output method="xml" indent="yes"/> <xsl:function name="mf:group" as="node()*"> <xsl:param name="elements" as="element()*"/> <xsl:param name="level" as="xsd:integer"/> <xsl:for-each-group select="$elements" group-starting-with="p[@class eq concat('Head', $level)]"> <xsl:element name="sc{$level}"> <xsl:variable name="current-head" as="element()?" select="self::p[@class eq concat('Head', $level)]"/> <xsl:apply-templates select="$current-head"/> <xsl:variable name="max-level" select="max(for $h in current-group()[self::p[matches(@class, '^Head[0-9]+$')]] return xsd:integer(substring($h/@class, 5)))"/> <xsl:variable name="next-head" as="element()?" select="current-group()[self::p[matches(@class, '^Head[0-9]+$')]][1]"/> <xsl:variable name="v1" as="element()*" select="current-group()[. << $next-head] except $current-head"/> <xsl:apply-templates select="$v1"/> <xsl:choose> <xsl:when test="$level lt $max-level"> <xsl:sequence select="mf:group(current-group() except ($current-head, $v1), $level + 1)"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="current-group() except $current-head"/> </xsl:otherwise> </xsl:choose> </xsl:element> </xsl:for-each-group> </xsl:function> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@*, node()"/> </xsl:copy> </xsl:template> <xsl:template match="div[@class='bdy']"> <bdy> <xsl:variable name="v1" as="element()*" select="*[. << (current()/p[@class eq 'Head1' or @class eq 'Head2'])[1]]"/> <xsl:apply-templates select="$v1"/> <xsl:sequence select="mf:group(* except $v1, 1)"/> </bdy> </xsl:template> <xsl:template match="p[matches(@class, '^Head[0-9]+$')]"> <ti> <xsl:apply-templates/> </ti> </xsl:template> <xsl:template match="p[@class eq 'Para_FL']"> <p t="f1"> <xsl:apply-templates/> </p> </xsl:template> </xsl:stylesheet> It does not quite output what you want as you seem to want to group initially with group-starting-with="p[@class='Head1']|p[@class='Head2'] while the stylesheet above uses a single function that groups level by level (i.e. 'Head1', then 'Head2', then 'Head3' and so on). I am not sure there is an elegant way to fix that, other than implementing a second function for the special case of the initial grouping you want. -- Martin Honnen http://msmvps.com/blogs/martin_honnen/
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|