?
Solved

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

Posted on 2004-04-01
1
Medium Priority
?
744 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 500 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

This article was originally published on Monitis Blog, you can check it here . Today it’s fairly well known that high-performing websites and applications bring in more visitors, higher SEO, and ultimately more sales. By the same token, downtime…
Dramatic changes are revolutionizing how we build and use technology. Every company is automating, digitizing, and modernizing operations. We need a better, more connected way to work together as teams so we can harness the insights from our system…
The viewer will learn how to count occurrences of each item in an array.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses
Course of the Month8 days, 15 hours left to enroll

621 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