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

Re: Issue with nested grouping

Subject: Re: Issue with nested grouping
From: Florent Georges <lists@xxxxxxxxxxxx>
Date: Sun, 2 Dec 2007 20:49:43 +0100 (CET)
Re:  Issue with nested grouping
Geert Bormans wrote:

  Hi Geert,

> I have been looking at this for too long now, and I am
> still not sure why this doesn't work

> I have an XML (stripped down version of a word XML
> document) That requires (nested) grouping, based on the
> text content of some paragraphs.

  Personally, I wouldn't use for-each-group, but I would
traverse the W:P elements one by one, starting at the first
and then chaining the following sibling.

  If a W:P is starting a group, I create the group element
and I apply the next sibling as content of the group, then I
apply the next sibling of the corresponding ending group
(with the same id) after the newly created group element.

  If a W:P is ending a group, I do nothing (that's the end
recursion condition).

  In any other case I copy the node then I continue to the
next following sibling.

  Here below is a complete stylesheet that shows that.  Is
it what you are looking for?

  Regards,

--drkm


Welcome to the Emacs shell

~/xslt/tests $ cat geert.xsl
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
    xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"
    xmlns:my="my:geert.xsl"
    version="2.0"
    exclude-result-prefixes="my xs">

   <!-- ...........................................................
       Constant variables.
   -->
   <!-- RE matching the text of a group starting W:P/W:R/W:T. -->
   <xsl:variable name="group-start-re" select="
       '^\[start\s+pgroup\s+id=&quot;([^&quot;]+)&quot;.*$'"/>

   <!-- RE matching the text of a group ending W:P/W:R/W:T. -->
   <xsl:variable name="group-end-re" select="
       '^\[end\s+pgroup\s+id=&quot;([^&quot;]+)&quot;.*$'"/>

   <!-- ...........................................................
       Utility functions.
   -->
   <!-- Return the group id of a group starting W:P, may be (). -->
   <xsl:function name="my:group-start-id" as="xs:string?">
      <xsl:param name="p" as="element(w:p)"/>
      <xsl:analyze-string select="$p/w:r/w:t"
                          regex="{ $group-start-re }">
         <xsl:matching-substring>
            <xsl:sequence select="regex-group(1)"/>
         </xsl:matching-substring>
      </xsl:analyze-string>
   </xsl:function>

   <!-- Return the group id of a group ending W:P, may be (). -->
   <xsl:function name="my:group-end-id" as="xs:string?">
      <xsl:param name="p" as="element(w:p)"/>
      <xsl:analyze-string select="$p/w:r/w:t"
                          regex="{ $group-end-re }">
         <xsl:matching-substring>
            <xsl:sequence select="regex-group(1)"/>
         </xsl:matching-substring>
      </xsl:analyze-string>
   </xsl:function>

   <!-- Return the group ending W:P corresponding to a group starting
        W:P, may be (). -->
   <xsl:function name="my:group-closer" as="element(w:p)?">
      <xsl:param name="p" as="element(w:p)"/>
      <xsl:variable name="id" select="my:group-start-id($p)"/>
      <xsl:if test="exists($id)">
         <xsl:sequence select="
             $p/following-sibling::w:p[my:group-end-id(.) eq $id]"/>
      </xsl:if>
   </xsl:function>

   <!-- ...........................................................
       Main template rules.
   -->
   <!-- Identity template. -->
   <xsl:template match="node()">
      <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
   </xsl:template>

   <!-- Handle a WX:SUB-SECTION, start the grouping recursion over
        following siblings.  Launches the mode MY:GROUP. -->
   <xsl:template match="wx:sub-section">
      <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates select="w:p[1]" mode="my:group"/>
      </xsl:copy>
   </xsl:template>

   <!-- ...........................................................
       Mode: group.
   -->
   <!-- Handle a group starting W:P. -->
   <xsl:template match="w:p[exists(my:group-start-id(.))]"
                 mode="my:group">
      <pgroup id="{ my:group-start-id(.) }">
         <xsl:apply-templates mode="my:group" select="
             following-sibling::node()[1]"/>
      </pgroup>
      <xsl:apply-templates mode="my:group" select="
          my:group-closer(.)/following-sibling::node()[1]"/>
   </xsl:template>

   <!-- Handle a group ending W:P. -->
   <xsl:template match="w:p[exists(my:group-end-id(.))]"
                 mode="my:group"/>

   <!-- Identity template then recurse on the following sibling. -->
   <xsl:template match="node()" mode="my:group">
      <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
      <xsl:apply-templates mode="my:group" select="
          following-sibling::node()[1]"/>
   </xsl:template>

</xsl:stylesheet>

~/xslt/tests $ cat geert.xml 
<?xml version="1.0" encoding="UTF-8"?>
<w:wordDocument
    xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
    xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint">
   <w:body>
      <wx:sect>
         <wx:sub-section>
            <w:p>
               <w:r><w:t>Text before first pgroup</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>[start pgroup id="43210023"</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>First P in pgroup</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>Second P in pgroup.</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>[start pgroup id="54320024"</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>P in nested pgroup</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>[end pgroup id="54320024"</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>First P after nested group</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>[end pgroup id="43210023"</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>In between</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>Other In between</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>[start pgroup id="43210025"</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>[start pgroup id="54320026"</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>Isolated nested pgroup</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>[end pgroup id="54320026"</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>[end pgroup id="43210025"</w:t></w:r>
            </w:p>
         </wx:sub-section>
      </wx:sect>
   </w:body>
</w:wordDocument>

~/xslt/tests $ saxon geert.xml geert-my.xsl
<?xml version="1.0" encoding="UTF-8"?><w:wordDocument
xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml"
xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint">
   <w:body>
      <wx:sect>
         <wx:sub-section><w:p>
               <w:r><w:t>Text before first pgroup</w:t></w:r>
            </w:p>
            <pgroup id="43210023">
            <w:p>
               <w:r><w:t>First P in pgroup</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>Second P in pgroup.</w:t></w:r>
            </w:p>
            <pgroup id="54320024">
            <w:p>
               <w:r><w:t>P in nested pgroup</w:t></w:r>
            </w:p>
            </pgroup>
            <w:p>
               <w:r><w:t>First P after nested group</w:t></w:r>
            </w:p>
            </pgroup>
            <w:p>
               <w:r><w:t>In between</w:t></w:r>
            </w:p>
            <w:p>
               <w:r><w:t>Other In between</w:t></w:r>
            </w:p>
            <pgroup id="43210025">
            <pgroup id="54320026">
            <w:p>
               <w:r><w:t>Isolated nested pgroup</w:t></w:r>
            </w:p>
            </pgroup>
            </pgroup>
         </wx:sub-section>
      </wx:sect>
   </w:body>
</w:wordDocument>

~/xslt/tests $ 





      _____________________________________________________________________________ 
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail 

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.