15

I'm using the new System.Xml.Linq to create HTML documents (Yes, I know about HtmlDocument, but much prefer the XDocument/XElement classes). I'm having a problem inserting   (or any other HTML entity). What I've tried already:

  1. Just putting text in directly doesn't work because the & gets turned int &. new XElement("h1", "Text to keep together.");

  2. I tried parsing in the raw XML using the following, but it barfs with this error:

    XElement.Parse("Text to keep together.");

    --> Reference to undeclared entity 'nbsp'.`

  3. Try number three looks like the following. If I save to a file, there is just a space, the   gets lost.


var X = new XDocument(new XElement("Name", KeepTogether("Hi Mom!")));
private static XNode KeepTogether(string p)`
{
    return XElement.Parse("<xml>" + p.Replace(" ", "&#160;") + "</xml>").FirstNode;
}

I couldn't find a way to just shove the raw text through without it getting escaped. Am I missing something obvious?

Eric
  • 2,029
  • 2
  • 26
  • 36

8 Answers8

18

I couldn't find a way to just shove the raw text through without it getting escaped.

Just put the Unicode character in that &nbsp; refers to (U+00A0 NO-BREAK SPACE) directly in a text node, then let the serializer worry about whether it needs escaping to &#160; or not. (Probably not: if you are using UTF-8 or ISO-8859-1 as your page encoding the character can be included directly without having to worry about encoding it into an entity reference or character reference).

new XElement("h1", "Text\u00A0to\u00A0keep\u00A0together");
bobince
  • 528,062
  • 107
  • 651
  • 834
2

Replacing the & with a marker like ##AMP## solved my problem. Maybe not the prettiest solution but I got a demo for a customer in 10 mins so...I don't care :)

Thx for the idea

Daniel
  • 21
  • 1
  • Seems to be the only way I have found either, when you REALLY need the actual ouput string to have, for instance, an ` ` in it and not an actual newline or `&#10;` – Adam Nofsinger Jun 28 '10 at 15:58
2

I know this is old, but I found something and I'm rather surprised!

XElement element = new XElement("name",new XCData("<br /> & etc"));

And there you go! CDATA text!

Dan
  • 12,808
  • 7
  • 45
  • 54
  • The problem is that result of (new XElement("name",new XCData(" "))).ToString is <![CDATA[ ]]>. – IvanH Sep 19 '12 at 07:56
1

You could also try using numbered entities, they need no declaration. Numbered entity equivalent to the named entity &nbsp; is &#160;

baretta
  • 7,385
  • 1
  • 25
  • 25
1

Unlike amp (&), lt (<) etc, nbsp is not known entity to XML, so you need to declare it. In XML, e.g. &xyz; is treated as an entity, The parser will reference its value to produce the output.

// the xml, plz remove '.' within xml
string xml = "<xml>test&.n.b.s.p;test</xml>";

// declare nbsp as xml entity and its value is " " in this case.
string declareEntity = "<!DOCTYPE xml [<!ENTITY nbsp \" \">]>";

XElement x = XElement.Parse( declareEntity  + xml );
// output with a space between tests
// <xml>test test</xml>

or

 // plz remove '.' in the string 
 XElement.Parse("<xml>" + HttpUtility.HtmlEncode("Text&.n.b.s.p;keep everything") + "</xml>");
Ray Lu
  • 26,208
  • 12
  • 60
  • 59
  • This allows parsing in the XML. However, if I add do an x.Save("test.xml"), the output file has a space character instead of   between the two test words. Argh!!! – Eric Feb 25 '09 at 21:19
  • Can you replace space with &nbsp when needed? e.g. in HTML context. – Ray Lu Feb 25 '09 at 21:24
  • I'm creating a large html document, and then do a doc.Save(). This location is deep in the document, and not easily findable. For now I'm going to hack it and remove the space (its between a time and AM/PM). 6:30PM will be fine. Thanks for your help, though! – Eric Feb 25 '09 at 21:50
1

You can paste the character as you wish to see it if you copy it somewhere else. Viusal studio allows that. Though this is hard to do if you need  , it is easy if you need any symbols, for example:

&bull ...just paste •

&harr; ...just paste ↔

Arjan
  • 11
  • 1
0

I came up with this slightly daft approach which suits me: String replace all the & with ##AMP## when you store the data.... And reverse that operation on output. I am using this in conjunction with XElement SQL column and works a treat.

Regards

Neil

  • Not necessarily daft -- seemed to be faster than an "extra" `Parse` for me -- http://stackoverflow.com/questions/5723146/is-there-an-xelement-equivalent-to-xmlwriter-writeraw/21098659#21098659 – drzaus Jan 13 '14 at 18:31
-1
&amp;nbsp;
Brian Dilley
  • 3,888
  • 2
  • 24
  • 24