You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cocoon.apache.org by Zhu Di <fl...@gmail.com> on 2006/07/18 15:38:53 UTC

XSL for nested sql result

hello all,

I need some advice for writing a xsl for a nested sql result.
the source file is

 <rowset>
   <row>
     <id>test</id>
     <rowset>
       <row>
         <class_name> 111</class_name>
         <rowset>
           <row>
             <class_name> 11</class_name>
             <rowset>
               <row>
                 <class_name> 1</class_name>
                 <rowset>
                   <row>
                     <class_name>0</class_name>
                   </row>
                 </rowset>
               </row>
             </rowset>
           </row>
         </rowset>
       </row>
     </rowset>
   </row>
</rowset>

I want the result as 0/1/11/111,
and the total number of <class_name> are uncertain, (nested layer can be
more). the xsl need to be reusable for different numbers of  <class_name>
any hints?
I had try to use [ position()=last() ], but because of the nested structure,
it always get the first one

di

Re: XSL for nested sql result

Posted by Zhu Di <fl...@gmail.com>.
yes, I had define the namespace. and there is no big difference between the
<xsl:text>is inside or outside

2006/7/19, Toby <to...@linux.it>:
>
> Did you define the sql: namespace in the stylesheet?  Otherwise, use
> non-qualified element names: "rowset/row/rowset/row".
>
> Also <xsl:text>/</xsl:text> should be inside the if.
>
>
> Toby
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
> For additional commands, e-mail: users-help@cocoon.apache.org
>
>

Re: XSL for nested sql result

Posted by Toby <to...@linux.it>.
Did you define the sql: namespace in the stylesheet?  Otherwise, use
non-qualified element names: "rowset/row/rowset/row".

Also <xsl:text>/</xsl:text> should be inside the if.


Toby

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: XSL for nested sql result

Posted by Zhu Di <fl...@gmail.com>.
yes, I had add some test code inside <xsl:if test=" sql:rowset">, and found
that the code inside if never been used. but the element sql:rowset are
exist. quite strange...


2006/7/19, Zhu Di <fl...@gmail.com>:
>
>  I had try Toby's solution, but still I only can get the result as /111.
> the recursion apply-template at least should return the last class_name, but
> why it still only catch the first one...
>
> here is my code, with small modification on Toby's solution
>
>
> <
> xsl:template match="/">
>   < data>
>     <xsl:apply-templates select="sql:rowset/sql:row/sql:rowset/sql:row "mode
> ="class-string"/>
>   </data >
> </xsl:template>
>
>  <xsl:template match="sql:row" mode ="class-string">
>   <xsl:if test=" sql:rowset">
>     <xsl:apply-templates select="sql:rowset/sql:row " mode="class-string
> "/>
>   </xsl:if >
>   <xsl:text>/</xsl:text >
>   <xsl:value-of select="normalize-space( sql:class_name ) "/>
> </xsl:template>
>
> </xsl:stylesheet>
> and the result is <data>/111</data>
>
>
> 2006/7/18, spam2006@meeque.de <sp...@meeque.de>:
>
> > > I need some advice for writing a xsl for a nested sql result.
> > > the source file is
> > >
> > >  <rowset>
> > >    <row>
> > >      <id>test</id>
> > >      <rowset>
> > >        <row>
> > >          <class_name> 111</class_name>
> > >          <rowset>
> > >            <row>
> > >              <class_name> 11</class_name>
> > >              <rowset>
> > >                <row>
> > >                  <class_name> 1</class_name>
> > >                  <rowset>
> > >                    <row>
> > >                      <class_name>0</class_name>
> > >                    </row>
> > >                  </rowset>
> > >                </row>
> > >              </rowset>
> > >            </row>
> > >          </rowset>
> > >        </row>
> > >      </rowset>
> > >    </row>
> > > </rowset>
> > >
> > > I want the result as 0/1/11/111,
> >
> > Ok, Toby was faster than me, and actually I like his solution better.
> > Nevertheless, here is a non-recursive solution to your problem. You can
> > insert the following snippet somewhere in your stylesheet, where a node
> > containing your outermost class_name element is the context node:
> >
> > <xsl:for-each select="descendant::class_name">
> > <xsl:sort select="position()" order="descending"/>
> > <xsl:value-of select="normalize-space(.)"/>
> > <xsl:if test="position() != last()">
> >    <xsl:text>/</xsl:text>
> > </xsl:if>
> > </xsl:for-each>
> >
> > If you want to be more typesafe, use "descendant::rowset/row/class_name"
> >
> > in the first select attribute instead.
> >
> > Regards,
> > Michael
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
> > For additional commands, e-mail: users-help@cocoon.apache.org
> >
> >
>
>

Re: XSL for nested sql result

Posted by Zhu Di <fl...@gmail.com>.
I had try Toby's solution, but still I only can get the result as /111. the
recursion apply-template at least should return the last class_name, but why
it still only catch the first one...

here is my code, with small modification on Toby's solution


<xsl:template match="/">
  <data>
    <xsl:apply-templates select="sql:rowset/sql:row/sql:rowset/sql:row" mode
="class-string"/>
  </data>
</xsl:template>

 <xsl:template match="sql:row" mode="class-string">
  <xsl:if test="sql:rowset">
    <xsl:apply-templates select="sql:rowset/sql:row" mode="class-string"/>
  </xsl:if>
  <xsl:text>/</xsl:text>
  <xsl:value-of select="normalize-space( sql:class_name )"/>
</xsl:template>

</xsl:stylesheet>
and the result is <data>/111</data>


2006/7/18, spam2006@meeque.de <sp...@meeque.de>:
>
> > I need some advice for writing a xsl for a nested sql result.
> > the source file is
> >
> >  <rowset>
> >    <row>
> >      <id>test</id>
> >      <rowset>
> >        <row>
> >          <class_name> 111</class_name>
> >          <rowset>
> >            <row>
> >              <class_name> 11</class_name>
> >              <rowset>
> >                <row>
> >                  <class_name> 1</class_name>
> >                  <rowset>
> >                    <row>
> >                      <class_name>0</class_name>
> >                    </row>
> >                  </rowset>
> >                </row>
> >              </rowset>
> >            </row>
> >          </rowset>
> >        </row>
> >      </rowset>
> >    </row>
> > </rowset>
> >
> > I want the result as 0/1/11/111,
>
> Ok, Toby was faster than me, and actually I like his solution better.
> Nevertheless, here is a non-recursive solution to your problem. You can
> insert the following snippet somewhere in your stylesheet, where a node
> containing your outermost class_name element is the context node:
>
> <xsl:for-each select="descendant::class_name">
> <xsl:sort select="position()" order="descending"/>
> <xsl:value-of select="normalize-space(.)"/>
> <xsl:if test="position() != last()">
>    <xsl:text>/</xsl:text>
> </xsl:if>
> </xsl:for-each>
>
> If you want to be more typesafe, use "descendant::rowset/row/class_name"
> in the first select attribute instead.
>
> Regards,
> Michael
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
> For additional commands, e-mail: users-help@cocoon.apache.org
>
>

Re: XSL for nested sql result

Posted by "spam2006@meeque.de" <sp...@meeque.de>.
> I need some advice for writing a xsl for a nested sql result.
> the source file is
>  
>  <rowset>
>    <row>
>      <id>test</id>
>      <rowset>
>        <row>
>          <class_name> 111</class_name>
>          <rowset>
>            <row>
>              <class_name> 11</class_name>
>              <rowset>
>                <row>
>                  <class_name> 1</class_name>
>                  <rowset>
>                    <row>
>                      <class_name>0</class_name>
>                    </row>
>                  </rowset>
>                </row>
>              </rowset>
>            </row>
>          </rowset>
>        </row>
>      </rowset>
>    </row>
> </rowset>
>  
> I want the result as 0/1/11/111,

Ok, Toby was faster than me, and actually I like his solution better.
Nevertheless, here is a non-recursive solution to your problem. You can
insert the following snippet somewhere in your stylesheet, where a node
containing your outermost class_name element is the context node:

<xsl:for-each select="descendant::class_name">
  <xsl:sort select="position()" order="descending"/>
  <xsl:value-of select="normalize-space(.)"/>
  <xsl:if test="position() != last()">
    <xsl:text>/</xsl:text>
  </xsl:if>
</xsl:for-each>

If you want to be more typesafe, use "descendant::rowset/row/class_name"
in the first select attribute instead.

Regards,
Michael


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: XSL for nested sql result

Posted by Toby <to...@linux.it>.
Zhu Di wrote:
> <rowset>
>   <row>
>     <id>test</id>
>     <rowset>
>       <row>
>         <class_name> 111</class_name>
>         <rowset>
>           <row>
>             <class_name> 11</class_name>
>             <rowset>
>               <row>
>                 <class_name> 1</class_name>
>                 <rowset>
>                   <row>
>                     <class_name>0</class_name>
>                   </row>
>                 </rowset>
>               </row>
>             </rowset>
>           </row>
>         </rowset>
>       </row>
>     </rowset>
>   </row>
> </rowset>
> 
> I want the result as 0/1/11/111

...
<xsl:apply-templates select="rowset/row[id='test']/rowset/row" 
                     mode="class-string"/>
...

<xsl:template match="row" mode="class-string">
  <xsl:if test="rowset">
    <xsl:apply-templates select="rowset/row" mode="class-string"/>
    <xsl:text>/</xsl:text>
  </xsl:if>
  <xsl:value-of select="normalize-space(class_name)"/>
</xsl:template>


Toby

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org


Re: XSL for nested sql result

Posted by Bertrand Delacretaz <bd...@apache.org>.
On 7/18/06, Zhu Di <fl...@gmail.com> wrote:

>... I need some advice for writing a xsl for a nested sql result. ..

I think you will need to write a recursive template to do this, I have
a few bookmarks about that at
http://del.icio.us/bdelacretaz/xslt+recursion

-Bertrand

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@cocoon.apache.org
For additional commands, e-mail: users-help@cocoon.apache.org