2

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

DonutReply
  • 3,184
  • 6
  • 31
  • 34
  • Can you not just write `
    `? Perhaps I'm misunderstanding something...
    – Matt Gibson Sep 13 '10 at 15:16
  • because that would lead to mismatched and overlapping tags in xslt – DonutReply Sep 13 '10 at 15:21
  • Of course. Sorry, having a dumb moment. – Matt Gibson Sep 13 '10 at 15:25
  • 2
    You wrote `I need to open a div in one if statement and close it in another`. You are wrong. That's imperative paradigm way of thinking. You need to refrase that question as "I need to wrap some content template with a `div` element depending on some condition" –  Sep 13 '10 at 15:30
  • 1
    see my answer for a way to conditionally wrap some content with a `
    ` element, without subverting XSLT.
    – LarsH Sep 13 '10 at 17:20

4 Answers4

5

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
  • 27,481
  • 8
  • 94
  • 152
  • 1
    +1 for a really good answer. If not the OP, then someone else can learn from it. – Dimitre Novatchev Sep 13 '10 at 17:32
  • 1
    +1 for good general answer. Also, for some transformation you could use pattern mathching instead. –  Sep 13 '10 at 19:19
  • 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. – DonutReply Sep 17 '10 at 12:28
3

This works:

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

Thanks to @Alejandro for the tip in the comments

DonutReply
  • 3,184
  • 6
  • 31
  • 34
  • 1
    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 Sep 13 '10 at 17:13
1

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

Armstrongest
  • 15,181
  • 13
  • 67
  • 106
0

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)

Karmic Coder
  • 17,569
  • 6
  • 32
  • 42