xsl-list
[Top] [All Lists]

Re: splittingNode-set2

2004-08-09 08:51:39
Hi Manousos,
  Please try this XSL. It uses nodeset extension
function.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xalan="http://xml.apache.org/xalan";
exclude-result-prefixes="xalan">

<xsl:output method="xml" indent="yes"/>
        
<xsl:variable name="root" select="/" />
        
<xsl:template match="/ROWSET">
  <set>
     <xsl:variable name="rtf">
       <xsl:for-each
select="descendant::ELEM_INFO_ITEM">
         <xsl:if test="((position() mod 3) = 1) and
(position() &gt; 1)">
           <x>
             <xsl:value-of select="." />
           </x>
         </xsl:if>
       </xsl:for-each>  
     </xsl:variable>
            
     <xsl:for-each select="xalan:nodeset($rtf)/x">
       <xsl:variable name="a" select="." />
       <xsl:if test="position() &lt; last()">         

         <xsl:variable name="b"
select="following-sibling::x[1]" />
           <interior>             
             <xsl:copy-of
select="$root//ORDINATES_ITEM[(position() &gt; ($a -
1)) and (position() &lt; $b) ]" />
           </interior>
        </xsl:if>  
        <xsl:if test="position() = last()">
           <interior>
             <xsl:copy-of
select="$root//ORDINATES_ITEM[position() &gt; ($a -
1)]" />
           </interior>
        </xsl:if>
      </xsl:for-each>       
  </set>  
</xsl:template>
        
</xsl:stylesheet>

Regards,
Mukul

--- mankar(_at_)CENTRAL(_dot_)NTUA(_dot_)GR wrote:

Hallo,

Let me please rephrase my question concerning the
recursive splitting  of a
particular node set, in order to make it less
obscure.

I have this source xml

<?xml version="1.0" encoding="ISO-8859-7"?>
<ROWSET>
      <ROW num="1">
            <SHAPE>
                  <ELEM_INFO>
                       
<ELEM_INFO_ITEM>1</ELEM_INFO_ITEM>
                       
<ELEM_INFO_ITEM>1003</ELEM_INFO_ITEM>
                       
<ELEM_INFO_ITEM>50</ELEM_INFO_ITEM>

                       
<ELEM_INFO_ITEM>3</ELEM_INFO_ITEM>
                       
<ELEM_INFO_ITEM>2003</ELEM_INFO_ITEM>
                       
<ELEM_INFO_ITEM>50</ELEM_INFO_ITEM>

                       
<ELEM_INFO_ITEM>8</ELEM_INFO_ITEM>
                       
<ELEM_INFO_ITEM>2003</ELEM_INFO_ITEM>
                       
<ELEM_INFO_ITEM>50</ELEM_INFO_ITEM>
                  </ELEM_INFO>
                  <ORDINATES>
                       
<ORDINATES_ITEM>52</ORDINATES_ITEM>
                       
<ORDINATES_ITEM>45</ORDINATES_ITEM>
                       
<ORDINATES_ITEM>54</ORDINATES_ITEM> position 3
                       
<ORDINATES_ITEM>57</ORDINATES_ITEM>
                       
<ORDINATES_ITEM>76</ORDINATES_ITEM>
                       
<ORDINATES_ITEM>78</ORDINATES_ITEM>
                       
<ORDINATES_ITEM>56</ORDINATES_ITEM>
                       
<ORDINATES_ITEM>23</ORDINATES_ITEM> position 8
                       
<ORDINATES_ITEM>32</ORDINATES_ITEM>
                  </ORDINATES>
            </SHAPE>
      </ROW>
</ROWSET>

I want to use the ELEM_INFO_ITEM[position() mod 3 =
1][position() &gt; 1]
element's values, which are for this particular
example 3 and 8, as the
appropriate positions to split the ORDINATES_ITEM
node set into two
separate  nodes-sets.I mean select ORDINATE_ITEM
elements from position 3
to 7 as children of an interior element and
ORDINATE_ITEM elements from
position 8 to the last as children of another
interior element.
The desired output should look like:

<set>
<interior>
<ORDINATES_ITEM>54</ORDINATES_ITEM>
<ORDINATES_ITEM>57</ORDINATES_ITEM>
<ORDINATES_ITEM>76</ORDINATES_ITEM>
<ORDINATES_ITEM>78</ORDINATES_ITEM>
<ORDINATES_ITEM>56</ORDINATES_ITEM>
</interior>
<interior>
<ORDINATES_ITEM>23</ORDINATES_ITEM>
<ORDINATES_ITEM>32</ORDINATES_ITEM>
</interior>
</set>


This is easy to manage, when the source xml is
always the same, but it is
not.It is generated dynamically and the total number
of ELEM_INFO_ITEM
elements is different each time.This number is
always multiple of three, (9
in this example) and cannot be less than six.This
means that the number of
the generated interior elements also varies and
depends on the number of
ELEM_INFO_ITEM elements.

To be more specific i want, depending on my source
xml, to generate as many
interior elements as the
ELEM_INFO_ITEM[position()mod3=1][position()&gt; 1]
are, and i get to do this using something
like:

<xsl:for-each

select="ROWSET/ROW/SHAPE/ELEM_INFO/ELEM_INFO_ITEM[position()mod3=1][position()
 &gt;1]">
<interior>...</interior>
</xsl:for-each>

If i for example, had another source xml identical
with the first but with
the three last ELEM_INFO_ITEM elements missing, the
previous code would
generate exactly one interior element, as i wish it
to be.

The hard part is to select the appropriate
ORDINATE_ITEM nodes and pass
them as children to the relevant interior
element.Can i automate this task
through xslt code?
I mean, since the source is not always the same how
can i recursively
specify that the first interior element should
always contain ORDINATE_ITEM
elements whose position is greater than or equal to
ELEM_INFO_ITEM[position()mod3=1][2] and less than
ELEM_INFO_ITEM[position()mod3=1][3],
and the second interior element should always
contain ORDINATE_ITEM
elements whose position is greater than or equal to
ELEM_INFO_ITEM[position()mod3=1][3] and less than
ELEM_INFO_ITEM[position()mod3=1][4] etc.

How can i do this, since i can't know beforehand,
for example if an element
ELEM_INFO_ITEM[position()mod3=1][4]exists, as this
always depends on my
source xml.Is there a way to recursively define the
appropriate ceiling and
threshold ORDINATE_ITEM position for each sequential
interior element.

Please,let me know if  there is a way to obtain
this.


Regards
Manousos
Athens



                
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail


<Prev in Thread] Current Thread [Next in Thread>