0

I have text in a node, that contains html-like carriage-return <br/>. I want to keep this empty nodes within an XSLT conversion, but I do not succeed.

Here is an example XML-input:

<?xml version="1.0"?>
<eventlist>
  <event>
     <summary>Meeting Harry</summary>
     <description>Talk for Mistex Project<br/>Invite Spec</description>
  </event>
  <event>
    <summary>Shopping with Lance</summary>
    <description>Need Christmas Gift<br/>Joint Lunch<br/>Check for car</description>
  </event>
</eventlist>

Please note the <br/>'s between the <description>-nodes. While transforming to html, I want to keep the <br/>'s, the result should be something like

 <?xml version="1.0" encoding="iso-8859-1"?>
 <table>
    <tbody>
       <tr>
          <td>Meeting Harry</td>
          <td>Talk for Mistex Project<br/>Invite Spec</td>
       </tr>
       <tr>
          <td>Shopping with Lance</td>
          <td>Need Christmas Gift<br/>Joint Lunch<br/>Check for car</td>
       </tr>
    </tbody>
 </table>

But using the following very simple XSLT

  <!-- ******************************** -->
  <xsl:template match="/">
    <table>
      <tbody>
        <xsl:apply-templates select="eventlist/event"/>
      </tbody>
    </table>
  </xsl:template>
  <!-- ******************************** -->
  <xsl:template match="event">
    <tr>
      <td>
        <xsl:value-of select="summary"/>
      </td>
      <td>
        <xsl:apply-templates select="description"/>
      </td>
    </tr>
  </xsl:template>
  <!-- ******************************** -->
  <xsl:template match="description">
    <xsl:value-of select="."/>
    <xsl:apply-templates select="br"/>
  </xsl:template>
  <!-- ******************************** -->
  <xsl:template match="br">
    <br/>
  </xsl:template>
  <!-- ******************************** -->

</xsl:stylesheet>

I get something weird like

 <?xml version="1.0" encoding="iso-8859-1"?>
 <table>
    <tbody>
       <tr>
          <td>Meeting Harry</td>
          <td>Talk for Mistex ProjectInvite Spec<br/>
          </td>
       </tr>
       <tr>
          <td>Shopping with Lance</td>
          <td>Need Christmas GiftJoint LunchCheck for car<br/>
             <br/>
          </td>
       </tr>
    </tbody>
 </table>

The carriage returns are misplaced at the end of the description. The <xsl:value-of select="."/> just ommits the intermediate nodes, what is expectable. I just don't have solution for that, maybe there is a complete easy one? I don't get the <br/> on the right place. What am I doing wrong???

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
Magnum
  • 43
  • 4

1 Answers1

1

Why don't you just apply-templates inside of the description match instead of using value-of, there is no need for that.

<xsl:template match="description">
    <!--<xsl:value-of select="."/>-->
    <xsl:apply-templates/>
</xsl:template>

Result:

<table>
    <tbody>
        <tr>
            <td>Meeting Harry</td>
            <td>Talk for Mistex Project<br/>Invite Spec</td>
        </tr>
        <tr>
            <td>Shopping with Lance</td>
            <td>Need Christmas Gift<br/>Joint Lunch<br/>Check for car</td>
        </tr>
    </tbody>
</table>
Marcin
  • 190
  • 12
  • I've known it MUST be easy. Thanks for this deliverance...! It tortured me for hours... – Magnum Mar 05 '15 at 10:23
  • @Magnum consider reading about build-in templates in XSLT (http://www.w3.org/TR/xslt#built-in-rule), also this might be helpful: http://stackoverflow.com/questions/3360017/why-does-xslt-output-all-text-by-default – Marcin Mar 05 '15 at 10:32
  • Why don't you simply remove the template altogether - as it indeed does nothing that the built-in template rules don't do already. – michael.hor257k Mar 05 '15 at 11:12
  • I know you are not a fan of using templates as I have seen your answers before but you cannot force other people to use for-each selector over templates/apply-templates. http://stackoverflow.com/questions/6342902/for-loops-vs-apply-templates – Marcin Mar 05 '15 at 12:27
  • @Marcin You are quite wrong about my preferences, but this has nothing to do with it. The template above, after your suggested correction, is entirely redundant. You can remove it and the stylesheet will continue to function in the same way - because a built-in template rule will provide the same functionality. It's kind of ironic that at the same time you suggest reading about built-in templates to others, you don't see this yourself. – michael.hor257k Mar 05 '15 at 20:57
  • yes very ironic - let's teach XSLT newbies to use xsl:for-each over xsl:templates, bye. – Marcin Mar 06 '15 at 13:49
  • I suggest you keep to the topic and refrain from personal attacks. – michael.hor257k Mar 06 '15 at 20:05
  • Nevertheless, thanks to all. This build-in templates were in fact unknown to me. I've "used" this effect already before, without knowing it... ;-) By checking these earlier XSLT's created by me, I almost got crazy because I did not understand why text parts in sub-nodes have been translated by the XSLT without defining a rule for it. Now I know! – Magnum Mar 16 '15 at 11:25