3

Im trying to create automatic spacing in a XSL document in the following manner.

<td><xsl:value-of select="Name/First"/> <xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text><xsl:value-of select="Name/Last"/> </td> However, the rendered HTML is of the following form

<td>John&amp;nbsp;Grisham</td>

Any idea on how I could fix this?

seeker
  • 6,841
  • 24
  • 64
  • 100
  • Possible duplcate of: http://stackoverflow.com/questions/31870/using-a-html-entity-in-xslt-e-g-nbsp – Clint Apr 03 '13 at 22:03

2 Answers2

12

Your immediate problem is that while unicode 160 (hex 0xA0) &nbsp; is an HTML entity, it is not an XML entity.

Use &#160; or &#xA0; for non-breaking-space instead.

However for your larger problem, how to handle white space in XSL, the answer is simply this: Use <xsl:text>.

Every time you include ANY plain text, enclose it in <xsl:text> the text goes here </xsl:text> tags. If you don't you will be in for a world of pain the next time a clever text editor reformats your document.

You are already in for at least a Continent, or possibly if you are lucky a Country of pain, for expecting XML/XSL to conserve whitespace. Even geniuses who understand XSL to the nth degree still get County or at least Borough level pain from whitespace handling. (Borough level pain is encoded in the XML spec, "2.11 End-of-Line Handling" by its insane design decision to refuse to distinguish between LF and CRLF - so nobody can avoid that).

Just so you know what to expect: It isn't easy - you can get away without the <xsl:text> tags for a surprisingly long time, but if you just accept it, and put them in from the get-go, it will be easier in the long run.

Example WRONG:

  <xsl:element name="MyElem">
      <xsl:attribute name="fullPath">c:\base\Path\here\<xsl:value-of select="../parent/@relPath"/>\<xsl:value-of select="@fileName">
      </xsl:attribute>
  </xsl:element>

Example RIGHT:

  <xsl:element name="MyElem">
      <xsl:attribute name="fullPath">
          <xsl:text>c:\base\Path\here\</xsl:text>
          <xsl:value-of select="../parent/@relPath"/>
          <xsl:text>\</xsl:text>
          <xsl:value-of select="@fileName">
      </xsl:attribute>
  </xsl:element>

The thing is, they both produce exactly the same output.

But one of them will be messed up at some point in the future, yes, possibly by someone as yet unborn, the other will not.

The short-ish explanation is this: Nodes consisting ONLY OF WHITESPACE are ignored by default (unless you tweak the options). So that is anything consisting only of CR, LF, TAB and SPACE between > and <. Nodes consisting of non-whitespace text, with leading and trailing whitespace, may have whitespace "folded" - I.e. effed up.

So the difference between the Example RIGHT and this:

  <xsl:element name="MyElem">
      <xsl:attribute name="fullPath">
          c:\base\Path\here\
          <xsl:value-of select="../parent/@relPath"/>
          \
          <xsl:value-of select="@fileName">
      </xsl:attribute>
  </xsl:element>

is that one generates <MyElem fullPath="c:\base\Path\here\relative\path\filename.txt"/> and the other, depending on the DOM options in force, generates one of these:

<MyElem fullPath="c:\base\Path\here\relative\path\filename.txt"/>
<MyElem fullPath="c:\base\Path\here\ relative\path \ filename.txt"/>
<MyElem fullPath="c:\base\Path\here\&#10;relative\path&#10;\&10;filename.txt"/>
<MyElem fullPath="c:\base\Path\here\&#9;&#10;relative\path&#9;&#10;\&#9;&10;&#9;filename.txt"/>

Only one of which was what you wanted... but any of which might be correct depending on the options in force...

Ben
  • 34,935
  • 6
  • 74
  • 113
0

Used this <xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp; and it worked!

seeker
  • 6,841
  • 24
  • 64
  • 100