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

Re: Re: The Solution -- Re: how to rearrange nodes bas

Subject: Re: Re: The Solution -- Re: how to rearrange nodes based on a dependency graph?
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Sat, 22 Dec 2001 10:44:49 -0800 (PST)
xml xsl rearrange nodes position
Hi Gunther,

> Well, instead of wondering about the
> specs, I discovered a related problem with your topological
> sort. As beautiful as it is, it disturbs document order where
> it isn't warranted by the dependencies. For example, let's
> say I have 3 cliques of dependent nodes and no link between
> them. What happens with top sort is that those three cliques
> are all intermingled. The trick is to keep the document sort
> order if it doesn't need to be changed. I may end up to go
> back to my naive check-off list approach (recurse through
> node list and walk the dependencies, always propagating a node
> set of already processed nodes, and checking that a node
> isn't in the done set before processing it. I couldn't make
> this to work only because I refused to use the node-set function.
> Now I am free to do so :-)
> 

Here's another solution, which "keeps the cliques" together.

Let's have the following source xml document:

<document xml:space="preserve">
    <frag id='1'>
        <requires>2</requires>
        <requires>3</requires>
    </frag>

    <frag id='2'>
        <requires>4</requires>
        <requires>5</requires>
    </frag>

    <frag id='3'>
        <requires>5</requires>
    </frag>

    <frag id='4' />

    <frag id='5' />
    
    <frag id='6'>
        <requires>7</requires>
        <requires>8</requires>
    </frag>

    <frag id='7'>
        <requires>9</requires>
    </frag>
    
    <frag id='8'>
        <requires>9</requires>
    </frag>

    <frag id='9'>
        <requires>10</requires>
        <requires>11</requires>
    </frag>

     <frag id='10' />

    <frag id='11' />
   
</document>

This contains "two cliques" which are graphically represented bellow:

       1
      / \
     2   3
    / \ /
   4   5

and

       6
      / \
     7   8
      \ /
       9
      / \
     10 11

The algorithm is once again simple -- for every position on the list starting from
position 1 we move the element at this position right before the first preceding
element, that depends on it. Then we repeat this with the next position but with the
newly formed list, ... etc. until the last position has been treated.

Here's the stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
  <xsl:output indent="yes" omit-xml-declaration="yes"/>
  <xsl:template match="/">
    <xsl:call-template name="topSort">
      <xsl:with-param name="pList" select="/*/frag"/>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="topSort">
    <xsl:param name="pList" select="/.."/>
    <xsl:param name="pPositon" select="1"/>
    
    <xsl:choose>
      <xsl:when test="$pPositon > count($pList)">
        <xsl:copy-of select="$pList"/>
      </xsl:when>
      <xsl:otherwise>
	    <xsl:variable name="vThisNode" select="$pList[$pPositon]"/>
	    <xsl:variable name="vfirstPrecedingDependent"
	                  select="$pList[position() &lt; $pPositon
	                               and
	                                 requires = $vThisNode/@id
	                                 ][1]"/>
	    <xsl:variable name="vInsertPosition">
	      <xsl:choose>
	        <xsl:when test="$vfirstPrecedingDependent">
	          <xsl:value-of select="count($vfirstPrecedingDependent
                                                           /preceding-sibling::*)"/>
	        </xsl:when>
	        <xsl:otherwise>-1</xsl:otherwise>
	      </xsl:choose>
	    </xsl:variable> 
	    
	    <xsl:variable name="vrtfNewList">
	      <xsl:choose>
	        <xsl:when test="$vfirstPrecedingDependent">
	   	  <xsl:copy-of select="$pList[position() &lt;= $vInsertPosition]"/>
		  <xsl:copy-of select="$vThisNode"/>
		  <xsl:copy-of select="$pList[position() > $vInsertPosition
				            and
				              position() != $pPositon
				              ]"/>
		</xsl:when>
		<xsl:otherwise/>
	      </xsl:choose>
	    </xsl:variable>
		 
	    <xsl:variable name="vNewList" 
		          select="msxsl:node-set($vrtfNewList)
                                                      /*[$vfirstPrecedingDependent]
		                  | $pList[not($vfirstPrecedingDependent)]"/>
	    <xsl:call-template name="topSort">
	      <xsl:with-param name="pList" select="$vNewList"/>
	      <xsl:with-param name="pPositon" select="$pPositon + 1"/>
	   </xsl:call-template>
       </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

When applied on the above source xml document, this transformation produces the
following result:

<frag id="4" />
<frag id="5" />
<frag id="2">
        <requires>4</requires>
        <requires>5</requires>
</frag>
<frag id="3">
        <requires>5</requires>
</frag>
<frag id="1">
        <requires>2</requires>
        <requires>3</requires>
</frag>
<frag id="10" />
<frag id="11" />
<frag id="9">
       <requires>10</requires>
        <requires>11</requires>
</frag>
<frag id="7">
        <requires>9</requires>
</frag>
<frag id="8">
        <requires>9</requires>
</frag>
<frag id="6">
        <requires>7</requires>
        <requires>8</requires>
</frag>

As you can see, the two components of connectivity are not intermingled now.

Hope this helped.

Cheers,
Dimitre Novatchev.

__________________________________________________
Do You Yahoo!?
Send your FREE holiday greetings online!
http://greetings.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


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.