tags:

views:

157

answers:

5

Is there a way to open a tag and not close it? For example:

<xsl:for-each select=".">
       <span>
</xsl:for-each>

This is my code: http://pastebin.com/1Xh49YN0 . As you can see i need to open on a when tag and close it on another when tag (row 43 and 63).

This piece of code is not valid because XSLT is not well formed, but is there a way to do a similar thing? Thank you

A: 

You must need to close the tags always. You can't avoid that.

Dez
+1  A: 

You can't - XSLT isn't about generating a text file or a sequence of characters, it's about transforming one document tree into another. That the tree eventually gets serialized into a textual format is incidental.

This is why, for example, you can't choose between and in the output file - they're both represent exactly the same document tree.

You can almost always achieve what is intended by refactoring into separate templates that call each other.

Bevan
+4  A: 

Move the content between the two existing xsl:choose elements to a new template

In the xsl:when, open and close your span. Inside the span, call this new template.

Add an xsl:otherwise to the xsl:choose, in this, call the template, without adding a span.

As a general point, try to use xsl:apply-templates a bit more often, rather than xsl:for-each, it should make it easier to understand what is going on.

Paul Butcher
+1 `<xsl:for-each>` is unnecessary in 98% of all cases.
Tomalak
indeed, I can't think when I've ever used it.
Paul Butcher
A: 

You can use disable-output-escaping, but it's generally considered a bit of a hack, and I understand it's deprecated in XSLT 2.

Matthew Wilson
`disable-output-escaping` certainly is the wrong approach to this problem, deprecated or not.
Tomalak
A: 

Untested, obviously, but if I understood your original code correctly, this should be pretty close.

<xsl:choose>
    <xsl:when test="$pos">
        <xsl:for-each select="$s">
            <xsl:choose>
                <!-- inizio contesto -->
                <xsl:when test="$pos[.=position()+$context_number]">
                    <xsl:text>INIZIO CONTESTO</xsl:text>
                </xsl:when>
                <!-- fine contesto -->
                <xsl:when test="$pos[.=position()-$context_number]">
                    <xsl:text>FINE CONTESTO</xsl:text>
                </xsl:when>
                <!-- parola -->
                <xsl:when test="$pos[.=position()]">
                    <span class="word"><xsl:value-of select="."/></span>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
            <xsl:if test="position() != last()">
                <xsl:text> </xsl:text>
            </xsl:if>
        </xsl:for-each>
    </xsl:when>
    <xsl:otherwise>
        <!-- stampo tutta la riga -->
        <xsl:value-of select="$s"/>
    </xsl:otherwise>
</xsl:choose>

Hint: <xsl:when test="(. - $current_pos) eq 0"> is equivalent to <xsl:when test=".=$current_pos">. ;-)

Tomalak