tags:

views:

63

answers:

4

Basically I need to open a div in one if statement and close it in another. I tried

<xsl:value-of select="'<div>'"/>

but that failed because < and > aren't allowed in attributes. Any ideas? Cheers

A: 

This is generally bad practice, as you should always open and close the tags of your output at the same level. Otherwise, you are looking at a potential nightmare of "where was I supposed to close this?" questions down the road. That said, this may work:

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

(EDIT: Forgot to add output escaping)

Mike
Ah, cheers. Haven't tried it yet but it looks like it will work
Oliver
@Oliver: This doesn't work. For output a malformed tree you need DOE.
Alejandro
didn't work in the end, I was hoping the entities would be converted to actual < and > sign in the output
Oliver
@Alejandro - thanks, that did it
Oliver
+1  A: 

If you're just printing it out, you could use the html entities &lt; and &gt; stead of < and >.

Atømix
A: 

This works:

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

Thanks to @Alejandro for the tip in the comments

Oliver
@Oliver, as Mike said this is usually bad practice.. you should know that doing this usually indicates a confusion of markup and text. See http://www.dpawson.co.uk/xsl/sect2/N2215.html#d3702e223 If you tell us more about the scenario, we can probably tell you how to drive a screw with a screwdriver instead of a hammer!
LarsH
@Oliver, We shouldn't promote ultimately bad practices. You are here to *learn* something -- if not, simply don't use XSLT and keep using your comfy imperative language. You will not know what you have missed...
Dimitre Novatchev
+5  A: 

If what you want to do is output some content regardless of any condition, but wrap the content in a <div> depending on a condition:

  <xsl:choose>
     <xsl:when test="myConditionIsTrue">
        <div>
           <xsl:call-template name="bar"/>
        </div>
     </xsl:when>
     <xsl:otherwise>
        <xsl:call-template name="bar"/>            
     </xsl:otherwise>
  </xsl:choose>

You can change the <xsl:call-template> to <xsl:apply-templates> or <xsl:value-of select="$myvariable" /> etc. depending on what the invariant content is.

This way, you will be treating a tree structure as a tree structure, leveraging the power of an XML tree-based processor, instead of trying to fight against it. DOE may work in many instances, but it's not portable, because XSLT processors are not required to honor it. Indeed they can't, unless they happen to be responsible for serialization in a particular pipeline. The above method avoids this problem.

LarsH
+1 for a really good answer. If not the OP, then someone else can learn from it.
Dimitre Novatchev
@Dimitre thanks. :-)
LarsH
@LarsH: +1 for good general answer. Also, for some transformation you could use pattern mathching instead.
Alejandro
@Alejandro: good point about using template match patterns.
LarsH
@LarsH Thanks for you input, I appreciate that my method doesn't conform to best practice but I can't use your method as I'm using a a recursive template to loop through the creation of multiple divs with different widths and heights which stack into rows. Due to an internet explorer bug I needed to wrap all divs created after a certain iteration in a containing div which means I have to open the container div in one iteration of the template and close it in the last iteration. Maybe there's a neater way to do it but this worked.
Oliver