Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old February 27th, 2006, 05:17 PM
Registered User
 
Join Date: Feb 2006
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default preceding-sibling descendant

I am trying to put a list of class names in a table sometimes there needs to be 3 columns but most of the time there needs to be 4. If the Arg element in the XML is empty then there needs to be a </td></tr><tr> to close the sell and row and start another row. The below XSLT is not giving the desired result. This particular example is should be in 3 columns but the same XLST needs to be applicable for 3 and 4 columns.

Thanks in advance.

<xsl:template match="Group" >
    <table width="525">
        <tr>
            <td width="540" colspan="6"><xsl:value-of select="Header"/></td>
        </tr>
        <xsl:text disable-output-escaping="yes">
                &lt;tr&gt;
        </xsl:text>

        <xsl:for-each select="List/Course">

            <xsl:text disable-output-escaping="yes">
                &lt;td width="75" &gt;
            </xsl:text>
            <a href="javascript:poptastic('/myDegreePlanner/WebContent/jsps/coursedescription.jsp?course={Name}');"><xsl:value-of select="concat(Name,' ')"/> </a>
            <xsl:text disable-output-escaping="yes">
                &lt;/td&gt;
                &lt;td width="50" align="left" &gt;
            </xsl:text>
            <xsl:choose>
                <xsl:when test="Status = '(X)'">
                    <input name="" type="checkbox" disabled="true" value="" checked="checked" ></input>
                </xsl:when>
                <xsl:otherwise>
                    <input name="" type="checkbox" value="" />
                </xsl:otherwise>
            </xsl:choose>
            <xsl:value-of select="concat(Arg,' ')"/>
            <xsl:text disable-output-escaping="yes">
                    &lt;/td&gt;

            </xsl:text>

            <xsl:choose>
                <xsl:when test="Arg=''" >
                    <xsl:text disable-output-escaping="yes">
                        &lt;/tr&gt;&lt;tr&gt;

                    </xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:choose>
                    <xsl:when test="position() mod 4 = 0" >
                        <xsl:if test="preceding-sibling::*[1][descendant::Arg] !=''">
                            <xsl:text disable-output-escaping="yes">
                                    &lt;/tr&gt;&lt;tr&gt;
                            </xsl:text>
                        </xsl:if>

                    </xsl:when>
                    <xsl:otherwise>
                            <xsl:if test="preceding-sibling::*[1][descendant::Arg] =''">

                            </xsl:if>

                    </xsl:otherwise>
                     </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>

        </xsl:for-each>
        <xsl:text disable-output-escaping="yes">
            &lt;/tr&gt;
        </xsl:text>


    </table>
</xsl:template>

The XML looks like
<List>
                    <Course>
                        <Name>ORI2000</Name>
                        <Status>( )</Status>
                        <Arg>or</Arg>
                    </Course>
                    <Course>
                        <Name>SPC2016</Name>
                        <Status>( )</Status>
                        <Arg>or</Arg>
                    </Course>
                    <Course>
                        <Name>SPC2040</Name>
                        <Status>( )</Status>
                        <Arg/>
                    </Course>
                    <Course>
                        <Name>SPC2600</Name>
                        <Status>( )</Status>
                        <Arg>or</Arg>
                    </Course>
                    <Course>
                        <Name>MAC1102</Name>
                        <Status>( )</Status>
                        <Arg>or</Arg>
                    </Course>
                    <Course>
                        <Name>MAC1105</Name>
                        <Status>( )</Status>
                        <Arg/>
                    </Course>
                    <Course>
                        <Name>MAC1140</Name>
                        <Status>( )</Status>
                        <Arg>or</Arg>
                    </Course>
                    <Course>
                        <Name>MAC1114</Name>
                        <Status>( )</Status>
                        <Arg>or</Arg>
                    </Course>
                    <Course>
                        <Name>MAC1147</Name>
                        <Status>( )</Status>
                        <Arg/>
                    </Course>
                    <Course>
                        <Name>MAC2233</Name>
                        <Status>( )</Status>
                        <Arg>or</Arg>
                    </Course>
The results look like
ORI2000 or SPC2016 or SPC2040
SPC2600 or
MAC1102 or MAC1105
MAC1140 or MAC1114 or
MAC1147

 
Old February 27th, 2006, 07:07 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

This is not the way to write XSLT:

       <xsl:text disable-output-escaping="yes">
                &lt;tr&gt;
        </xsl:text>

XSLT is a language for transforming input trees into result trees. The result tree is then (optionally) sent to a serializer to be turned into serial XML. Very occasionally you need to prod the serializer to do something unusual, and that is the only time you should use disable-output-escaping. What you are trying to do here is to bend XSLT into a language for writing textual XML, in the form of tags, and you are getting yourself into a mess as a result.

Writing a node to a tree is an atomic action, achieved using a literal result element if it's name is known statically, or xsl:element if not. You don't write one half of the node at one time, and the other half later.

To write a table with data items arranged four per row, your logic should look like this:

<table>
 for each group of four items
  <tr>
    for each of the four items
      <td>
        output the item

for example

<table>
 <xsl:for-each select="Course[position() mod 4 = 1]">
  <tr>
   <xsl:for-each select=".|following-sibling::Course[position() &lt; 4]">
     <td>
       <xsl:apply-templates/>
     </td>
   </xsl:for-each>
  </tr>
 </xsl:for-each>
</table>

Sorry not to help you with your immediate problem, but this code is no place to start from.




Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old February 28th, 2006, 10:29 AM
Registered User
 
Join Date: Feb 2006
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thank you for your comment however this is only an example of my problem. The problem that I am trying to solve goes much deeper and I did not wish to go into the details on this list and thus far the only way that I can see to address it is to use the stratagy that I have employed. I welcome any comments that will help me address the issue of sibling descendancency.

Thank you



 
Old February 28th, 2006, 02:48 PM
Registered User
 
Join Date: Feb 2006
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

For anyone who is interested the solution to my problem is as follows.

<xsl:choose>
                <xsl:when test="position() mod 4 = 0" >
                    <xsl:if test="(preceding-sibling::*[1]/Arg !='' and following-sibling::*[1]/Arg !='') or position()=last()">
                        <xsl:text disable-output-escaping="yes">
                            &lt;/tr&gt;&lt;tr&gt;
                        </xsl:text>
                    </xsl:if>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:if test="Arg =''" >
                        <xsl:text disable-output-escaping="yes">
                            &lt;/tr&gt;&lt;tr&gt;
                        </xsl:text>
                    </xsl:if>
                </xsl:otherwise>

            </xsl:choose>
            <xsl:choose>
                <xsl:when test="position() mod 4 = 0" >
                    <xsl:if test="position()+1=last()" >
                        <xsl:text disable-output-escaping="yes">
                            &lt;/tr&gt;&lt;tr&gt;
                        </xsl:text>
                    </xsl:if>
                </xsl:when>
            </xsl:choose>







Similar Threads
Thread Thread Starter Forum Replies Last Post
preceding-sibling::comment() bonekrusher XSLT 11 October 1st, 2008 11:38 AM
Using preceding-sibling mcanne98 Infopath 0 September 11th, 2008 11:09 PM
Preceding-sibling question. lafilip XSLT 7 March 5th, 2007 12:35 PM
preceding-sibling jonesyp XSLT 2 November 22nd, 2005 12:29 PM
preceding-sibling behaviour andrewcday XSLT 6 December 3rd, 2004 03:24 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.