Solved

XSLT: open tag on first condition, close tag on second.  Breaks XML'ishness of XSLT.

Posted on 2004-04-01
1
712 Views
Last Modified: 2010-05-18
So this has been a problem I have been kicking around for awhile.  I have actually given up on doing it in XSLT and just ripped it out with the DOM in code and then cache the resulting html string at the application scope.

Nevertheless:

Assume an xml structure like so.

<root>
  <item num="1" />
  <item num="2" />
  <item num="3" >
      <item num="1" />
      <item num="2" />
      <item num="3" />
  </item>
  <item num="4" />
  <item num="5" />
</root>

And then assume that the output that I would like should look like this:
<ul>
    <li>1</li>
    <li>2</li>
    <li>3
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
    </li>
    <li>4</li>
    <li>5</li>
</ul>

There is of course explicit ways of having the output be displayed in that manner.  But of course it isn't that simple.

1. You don't know the depth of the node structure ahead of time.  It can conceivably be as deep as it wants to be, meaning the output would have to create new unordered list elements for each node depth.

2. Well there really isn't a number 2.

Now me being the sharp guy that I am found that we can locate the beginning of a new node depth with the directive: count(preceding-sibling::*)=0

and we can know we are at the end of a node depth group with the directive: count(following-sibling::*)=0

So we can simply make a nice <xsl:choose> group with three statements, if we are at the start of a node depth area begin the template with a "<ul>".  Then if we are at the end of a node depth area then end the template with a "</ul>".  And the xsl:otherwise would just output a simple <li>.  Easy.

Well, easy in theory (at least in the theory of how I would LIKE it to work)..

Of course it does'nt work because it has mismatched tags that then break the xml'ishness (technical term) of the xslt.

This is a puzzler.

Does anyone have a solution?

Below is the broken xslt template.  note the open <ul> in the first <xsl:when> and the closing <ul> in the second when statement.  Removing those will make it operational.

<xsl:template match="item">                  
      <xsl:choose>
            <xsl:when test="count(preceding-sibling::*)=0">
                  <ul>
                        <li>
                        <xsl:value-of select="@num " />
                        </li>
                  <xsl:apply-templates select="item" />      
                                    
            </xsl:when>
                  
            <xsl:when test="count(following-sibling::*)=0">
                        <li>
                        <xsl:value-of select="@num " />
                        </li>
                        
                  </ul>
                  <xsl:apply-templates select="item" />      
                              
            </xsl:when>
                  
            <xsl:otherwise>
                  <li>
                        <xsl:value-of select="@num " />
                  </li>
                  <xsl:apply-templates select="item" />      
            </xsl:otherwise>            
                  
      </xsl:choose>      
</xsl:template>
0
Comment
Question by:gregoftheweb
1 Comment
 

Accepted Solution

by:
jurn earned 125 total points
ID: 10738179
how about something like..

<xsl:template match="root">
    <ul>
      <xsl:apply-templates/>
    </ul>
</xsl:template>
<xsl:template match="item">
    <li>
      <xsl:value-of select="@num"/>
      <xsl:if test="item">
        <ul>
          <xsl:apply-templates/>
        </ul>
      </xsl:if>
    </li>
</xsl:template>

hope it helps.
jurn
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Get to know the ins and outs of building a web-based ERP system for your enterprise. Development timeline, technology, and costs outlined.
This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
Viewers will get an overview of the benefits and risks of using Bitcoin to accept payments. What Bitcoin is: Legality: Risks: Benefits: Which businesses are best suited?: Other things you should know: How to get started:
This video teaches users how to migrate an existing Wordpress website to a new domain.

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now