String escape into XML

Viewed 112898

Is there any C# function which could be used to escape and un-escape a string, which could be used to fill in the content of an XML element?

I am using VSTS 2008 + C# + .Net 3.0.

EDIT 1: I am concatenating simple and short XML file and I do not use serialization, so I need to explicitly escape XML character by hand, for example, I need to put a<b into <foo></foo>, so I need escape string a<b and put it into element foo.

11 Answers
public static string XmlEscape(string unescaped)
{
    XmlDocument doc = new XmlDocument();
    XmlNode node = doc.CreateElement("root");
    node.InnerText = unescaped;
    return node.InnerXml;
}

public static string XmlUnescape(string escaped)
{
    XmlDocument doc = new XmlDocument();
    XmlNode node = doc.CreateElement("root");
    node.InnerXml = escaped;
    return node.InnerText;
}

EDIT: You say "I am concatenating simple and short XML file and I do not use serialization, so I need to explicitly escape XML character by hand".

I would strongly advise you not to do it by hand. Use the XML APIs to do it all for you - read in the original files, merge the two into a single document however you need to (you probably want to use XmlDocument.ImportNode), and then write it out again. You don't want to write your own XML parsers/formatters. Serialization is somewhat irrelevant here.

If you can give us a short but complete example of exactly what you're trying to do, we can probably help you to avoid having to worry about escaping in the first place.


Original answer

It's not entirely clear what you mean, but normally XML APIs do this for you. You set the text in a node, and it will automatically escape anything it needs to. For example:

LINQ to XML example:

using System;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        XElement element = new XElement("tag",
                                        "Brackets & stuff <>");

        Console.WriteLine(element);
    }
}

DOM example:

using System;
using System.Xml;

class Test
{
    static void Main()
    {
        XmlDocument doc = new XmlDocument();
        XmlElement element = doc.CreateElement("tag");
        element.InnerText = "Brackets & stuff <>";
        Console.WriteLine(element.OuterXml);
    }
}

Output from both examples:

<tag>Brackets &amp; stuff &lt;&gt;</tag>

That's assuming you want XML escaping, of course. If you're not, please post more details.

George, it's simple. Always use the XML APIs to handle XML. They do all the escaping and unescaping for you.

Never create XML by appending strings.

Another take based on John Skeet's answer that doesn't return the tags:

void Main()
{
    XmlString("Brackets & stuff <> and \"quotes\"").Dump();
}

public string XmlString(string text)
{
    return new XElement("t", text).LastNode.ToString();
} 

This returns just the value passed in, in XML encoded format:

Brackets &amp; stuff &lt;&gt; and "quotes"

Using a third-party library (Newtonsoft.Json) as alternative:

public static string XmlEscape(string unescaped)
{
    if (unescaped == null) return null;
    return JsonConvert.SerializeObject(unescaped); ;
}

public static string XmlUnescape(string escaped)
{
    if (escaped == null) return null;
    return JsonConvert.DeserializeObject(escaped, typeof(string)).ToString();
}

Examples of escaped string:

a<b ==> "a&lt;b"

<foo></foo> ==> "foo&gt;&lt;/foo&gt;"

NOTE: In newer versions, the code written above may not work with escaping, so you need to specify how the strings will be escaped:

public static string XmlEscape(string unescaped)
{
    if (unescaped == null) return null;
    return JsonConvert.SerializeObject(unescaped, new JsonSerializerSettings()
    {
        StringEscapeHandling = StringEscapeHandling.EscapeHtml
    });
}

Examples of escaped string:

a<b ==> "a\u003cb"

<foo></foo> ==> "\u003cfoo\u003e\u003c/foo\u003e"

Related