230

How can I insert

 

Into an XSLT stylesheet, I keep getting this error:

XML Parsing Error: undefined entity

Essentially I want a non breaking space character in the XSLT Template.

NorthCat
  • 9,643
  • 16
  • 47
  • 50
JL.
  • 78,954
  • 126
  • 311
  • 459
  • 3
    You can also use   same to   look here http://stackoverflow.com/questions/7511214/what-is-the-difference-between-x00a0-and-160 – user3766111 Jun 23 '14 at 04:46

13 Answers13

363

Use the entity code   instead.

  is a HTML "character entity reference". There is no named entity for non-breaking space in XML, so you use the code  .

Wikipedia includes a list of XML and HTML entities, and you can see that there are only 5 "predefined entities" in XML, but HTML has over 200. I'll also point over to Creating a space ( ) in XSL which has excellent answers.

brabster
  • 42,504
  • 27
  • 146
  • 186
  • 3
    We ran into a situation recently where in just one of many XSL stopped working with this technique, and started showing a strange character. However, if I use WaterSoul's CDATA technique it works. –  Feb 10 '12 at 22:36
  • @BrianReindel, that probably means that you used the wrong numeric entity reference, i.e. `Š` instead of ` `, the latter which will always resolve to a Unicode non-breaking space. – Abel Sep 06 '15 at 11:18
  • The link [Top Ten Java and XSLT Tips](http://www.onjava.com/pub/a/oreilly/java/news/javaxslt_0801.html) is really useful. – LCJ Feb 05 '16 at 16:41
  •   it seperate the two fields – Manash Ranjan Dakua Dec 07 '17 at 05:40
  • 1
    The link has rotten. – GSerg Aug 08 '18 at 12:14
48

&#160; works really well. However, it will display one of those strange characters in ANSI encoding. <xsl:text> worked best for me.

<xsl:text> </xsl:text>
Saroj
  • 1,088
  • 11
  • 16
  • 3
    Using the accepted answer I ended up with a line breaking space in my XML output (at least that's what it looked like in VS2010's XML editor). Using this answer I get exactly 1 space only. – Mathijs Flietstra Jan 14 '14 at 15:00
  • 1
    @Matthijs, this is a space, not a non-breaking space, which is not the same. If VS shows it incorrectly, check your encoding (VS is perfectly capable of showing this correctly and it should be encoding independent, so more likely you were doing something else wrong). – Abel Sep 06 '15 at 11:22
26

One can also do this :

<xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text>
WaterSoul
  • 377
  • 3
  • 4
  • 2
    This will work *if the processor supports `disable-output-escaping`*, which it is not required to and it was deprecated in XSLT 2.0 and more so in 3.0. In these versions you can reach the same effect with `xsl:character-map` guaranteed to work cross-processor. Also, this places a named entity ` ` in the output, which *is not necessarily the same as a non-breaking space* and the receiving end *must have this entity declared* (in HTML it usually is implicitly). – Abel Sep 06 '15 at 11:17
23

Use this

<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;

edit: Downvoters should probably validate that this works first (it does, and is the most general solution to the problem.)

honk
  • 9,137
  • 11
  • 75
  • 83
jagprinderdeep
  • 396
  • 1
  • 4
  • I am worried about my mental condition. I'm pretty sure I've commented on the answer saying something like "why not use CDATA instead of explicitly encoding space". I do not see a trace of it, but I still have a morsel of confidence. Tell me, have you gone completely mad? – Michael Krelin - hacker Sep 22 '09 at 18:17
  • 1
    Not sure, but i've tested my approach and it works, so i'm not certain what the downvote was for :( – jagprinderdeep Sep 22 '09 at 18:19
  • 2
    Also, the accepted answer will not be valid for all parsers according to the linked page; just a heads up – jagprinderdeep Sep 22 '09 at 18:25
  • 1
    I've given the reason for my downvote before, but if I were to downvote *this* answer, then the reason would be - it answers the wrong question. The OP clearly asked how to put in nonbreakable space, using xslt and you answered how to put ampersand-n-b-s-p-semicolon sequence. And quarreling over downvotes is unnice too. But seriously, have you never ever said that about CDATA? – Michael Krelin - hacker Sep 22 '09 at 19:15
  • 1
    Okay, jagprinderdeep, I revoke my downvote, but in return please go visit me once I hit the mental asylum. (note that I don't give you the downvote back for that new reason). But do understand that you answer the wrong question. I think that was exactly the reason behind the other downvote. – Michael Krelin - hacker Sep 22 '09 at 19:37
  • 1
    @jagprinderdeep, searched for letterly like a week for a solution for adding a space. NOTHING WORKED!! But your solution worked! Thanks! I upvoted. – Yustme Oct 20 '10 at 09:52
  • 8
    I also downvoted as you can't guarantee the receiving end will declare  . If you're working with xslt+html, then yes, this is a way to do it, albeit a hack. But, if you're using xslt to generate other xml, then it'll just blow up at you. – Doug Feb 15 '11 at 19:38
  • 1
    Confirmed what @jagprinderdeep said about differing: I got an accented A from using the   entity when I used my XSL sheet through .Net 2. – Liam Dawson Jan 17 '12 at 16:12
  • The page referred by @Brabster listed a slightly different version of this which moved the "nbsp;" inside the xls:text tag. Either work fine for html. Not sure what the controversy is about. The OP said he wanted a non-beaking space so he is pretty obviously talking about html - xml has no such thing. xml parsers are not required to support the approach suggested by Brabster nor disabling output escaping per jagprinderdeep so those inclined should consider both as 'hacks'. – B H Jan 09 '13 at 17:20
  • The accented 'A' happens when you get your encoding wrong. The UTF-8 encoding for nbsp (in hex) is [C2][A0]. C2 in UTF-16 or Windows is `Â`, So, if you output   in UTF-8, but don't tell whatever's loading it in Windows that it's UTF-8, you'll see the  character. – Flynn1179 Nov 06 '15 at 13:21
  • Definitely a downvote to anything that uses disable-output-escaping. The reason is that it will only work if your transformation is closely coupled to a serializer. This makes your code less reusable; you can't for example deploy it in a pipeline of transformations except by serializing and reparsing the output. The people who upvote this are people who want instant gratification and don't think about the long term software life-cycle. – Michael Kay Jul 20 '18 at 16:56
17

You might want to add the definition for this entity in the beginning of the file (below xml declaration):

<!DOCTYPE stylesheet [
<!ENTITY nbsp  "&#160;" >
]>

Also you can add more entities such as Ntilde, Aacute, etc.

victor hugo
  • 35,514
  • 12
  • 68
  • 79
6

In addition to victor hugo's answer it is possible to get all known character references legal in an XSLT file, like this:

<!DOCTYPE stylesheet [
  <!ENTITY % w3centities-f PUBLIC "-//W3C//ENTITIES Combined Set//EN//XML"
      "http://www.w3.org/2003/entities/2007/w3centities-f.ent">
  %w3centities-f;
]>
...
<xsl:text>&amp; &nbsp; &ndash;</xsl:text>

There is also certain difference in the result of this approach as compared to <xsl:text disable-output-escaping="yes"> one. The latter is going to produce string literals like &nbsp; for all kinds of output, even for <xsl:output method="text">, and this may happen to be different from what you might wish... On the contrary, getting entities defined for XSLT template via <!DOCTYPE ... <!ENTITY ... will always produce output consistent with your xsl:output settings.

And when including all character references, it may be wise to use a local entity resolver to keep the XSLT engine from fetching character entity definitions from the Internet. JAXP or explicit Xalan-J users may need a patch for Xalan-J to use the resolver correctly. See my blog XSLT, entities, Java, Xalan... for patch download and comments.

Community
  • 1
  • 1
Sergey Ushakov
  • 2,425
  • 1
  • 24
  • 15
  • 1
    Note that recently, W3 started to block too many requests to those and similar links if coming from an automated process. Place that file locally or on your server and adjust the URL accordingly and you should be fine. Other than that, +1, and excellent solution to use HTML named entities. – Abel Sep 06 '15 at 11:23
  • A good note, and there is also another reason to have a local copy of the file with entity definitions, as otherwise XSLT process is likely to fail if internet connection is not available. In the Java world there is no need to hack URLs, as it is possible to arrange for an [EntityResolver](http://docs.oracle.com/javase/8/docs/api/org/xml/sax/EntityResolver.html), and [Apache XML Commons Resolver](http://xerces.apache.org/xml-commons/components/resolver/) may be a good candidate. Other programming platforms are likely to have similar techniques too... – Sergey Ushakov Sep 12 '15 at 05:11
  • Yes, so for reference, for the dotnetters: [ResolveEntity abstract method](https://msdn.microsoft.com/en-us/library/system.xml.xmlreader.resolveentity%28v=vs.110%29.aspx) for entities and [XmlResolver to load external resources](https://msdn.microsoft.com/en-us/library/system.xml.xmldocument.xmlresolver%28v=vs.110%29.aspx), which are the [.NET equivalents for these Java methods](http://stackoverflow.com/questions/942882/does-the-java-uriresolver-concept-exist-in-c-sharp-and-net). – Abel Sep 12 '15 at 09:18
3

XSLT stylesheets must be well-formed XML. Since "&nbsp;" is not one of the five predefined XML entities, it cannot be directly included in the stylesheet. So coming back to your solution "&#160;" is a perfect replacement of "&nbsp;" you should use.

Example:

<xsl:value-of select="$txtFName"/>&#160;<xsl:value-of select="$txtLName"/>
Adil
  • 89
  • 4
2

When you use the following (without disable-output-escaping!) you'll get a single non-breaking space:

<xsl:text>&#160;</xsl:text>

Abel
  • 56,041
  • 24
  • 146
  • 247
Shaam
  • 29
  • 3
1

Although answer has been already provided by @brabster and others.
I think more reusable solution would be:

<xsl:variable name="space">&#160;</xsl:variable>
...
<xsl:value-of select="$space"/>
Leonid Dashko
  • 3,657
  • 1
  • 18
  • 26
0

I was trying to display borders on an empty cell in an HTML table. My old trick of using non-breaking space in empty cells was not working from xslt. I used line break with the same effect. I mention this just in case the reason you were trying to use the non-breaking space was to give some content to an 'empty' table cell in order to turn on the cell borders.

<br/>
B H
  • 1,730
  • 18
  • 24
0

you can also use:

<xsl:value-of select="&#160;"/>
Mattia Vio
  • 134
  • 1
  • 6
  • This will output `&nbsp;` (assuming you intended to semicolon to be there), which will render as ` `, not as ` ` (nb-space). – Abel Sep 06 '15 at 11:25
0

Try to use

<xsl:text>&#160;</xsl:text>

But it depends on XSLT processor you are using: the XSLT spec does not require XSLT processors to convert it into "&nbsp;".

0

I do not know whether it is useful or not, but I have this work-about:

I define a new entity:

The healthy animal is up<nbsp />and<nbsp />do­ing.

Then I have a new defined template:

<xsl:template match="nbsp" >
    <xsl:text disable-output-escaping='yes'>&amp;nbsp;</xsl:text>
</xsl:template>

When parsed it gives:

"The healthy animal is up &nbsp; and &nbsp; doing"

I appreciate that <nbsp/> is almost as long as &nbsp;, so not much typing.

xerostomus
  • 466
  • 4
  • 11