Nerdio
Nerdio

Reputation: 1003

Line breaks occurring in XSLT template

I have some simple XML like this...

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <sentence>
        <word1>The</word1>
        <word2>cat</word2>
        <word3>sat</word3>
        <word4>on</word4>
        <word5>the</word5>
        <word6>mat</word6>
    </sentence>
    <sentence>
        <word1>The</word1>
        <word2>quick</word2>
        <word3>brown</word3>
        <word4>fox</word4>
        <word5>did</word5>
        <word6>nothing</word6>
    </sentence>
</root>

What I want to be able to do is process this with XSLT to create a sentence, like this The~cat~sat~on~the~mat

(This is a simplified example of what I ultimately want to be able to do, this is just a stumbling block for now).

My XSLT looks like this;

<?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="no" />
    <xsl:template match="text()[not(string-length(normalize-space()))]"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:text>&#xa;</xsl:text>
        <xsl:apply-templates />
     </xsl:template>  

    <xsl:template match="/root/sentence">
        <xsl:apply-templates />
        <xsl:text>&#xa;</xsl:text>
    </xsl:template>

    <xsl:template match="word1">
        <xsl:value-of select="text()" />
        ~
    </xsl:template>

    <xsl:template match="word2">
        <xsl:value-of select="text()" />
        ~
    </xsl:template>

    <xsl:template match="word3">
       <xsl:value-of select="text()" />
       ~
    </xsl:template>

    <xsl:template match="word4">
        <xsl:value-of select="text()" />
        ~
    </xsl:template>

    <xsl:template match="word5">
        <xsl:value-of select="text()" />
        ~
    </xsl:template>

    <xsl:template match="word6">
        <xsl:value-of select="text()" />
        ~
    </xsl:template>
</xsl:stylesheet>

If I run the stylesheet over the XML I get each word on a line of it s own, then a tilda on the next line, like this

<?xml version="1.0" encoding="UTF-8"?>
The
        ~
    cat
        ~
    sat
        ~
    on
        ~
    the
        ~
    mat
        ~

The
        ~
    quick
        ~
    brown
        ~
    fox
        ~
    did
        ~
    nothing
        ~

If I remove the tildas I get

Thecatsatonthemat

It looks to me then (and I am new to this XSLT stuff), that the inclusion of a tilda on a new line in the is forcing the new line.

So, how can I force the output from a template to all be on one line? (My final requirement is to do more formatting to the elements, and and spaces to pad elements out - I'll come to that later).

Thanks in anticipation

Upvotes: 0

Views: 1348

Answers (3)

mdelpeix
mdelpeix

Reputation: 187

Simply delete newline between <xsl:value-of select="text()" /> and ~ works for me

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="no" />
  <xsl:template match="text()[not(string-length(normalize-space()))]"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <xsl:text>&#xa;</xsl:text>
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="/root/sentence">
    <xsl:apply-templates />
    <xsl:text>&#xa;</xsl:text>
  </xsl:template>

  <xsl:template match="word1">
    <xsl:value-of select="text()" />~</xsl:template>

  <xsl:template match="word2">
    <xsl:value-of select="text()" />~</xsl:template>

  <xsl:template match="word3">
    <xsl:value-of select="text()" />~</xsl:template>

  <xsl:template match="word4">
    <xsl:value-of select="text()" />~</xsl:template>

  <xsl:template match="word5">
    <xsl:value-of select="text()" />~</xsl:template>

  <xsl:template match="word6">
    <xsl:value-of select="text()" />~</xsl:template>
</xsl:stylesheet>

result :

<?xml version="1.0" encoding="utf-8"?>
The~cat~sat~on~the~mat~
The~quick~brown~fox~did~nothing~

Upvotes: 0

JLRishe
JLRishe

Reputation: 101652

The reason this is happening is that when non-whitespace text appears directly between an xsl:template and its inner elements, all of the text that non-whitespace belongs to included in the result (including any whitespace). To avoid this, you should do this:

<xsl:template match="word1">
    <xsl:value-of select="concat(text(), '~')" />
</xsl:template>

I would also suggest eliminating those word1, word2, etc. templates that are almost identical, and replacing them with a single template:

<xsl:template match="*[starts-with(name(), 'word')]">
    <xsl:value-of select="concat(text(), '~')" />
</xsl:template>

Upvotes: 1

R Kaja Mohideen
R Kaja Mohideen

Reputation: 917

Change your ~ to <xsl:text>~</xsl:text>

Upvotes: 3

Related Questions