[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Group Techniques by xslt

Subject: Re: Group Techniques by xslt
From: Martin Honnen <Martin.Honnen@xxxxxx>
Date: Wed, 02 Dec 2009 19:10:31 +0100
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()[. &lt;&lt; $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="*[. &lt;&lt; (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/

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.