字符串转义为XML

时间:2009-07-15 16:30:57

标签: c# .net xml visual-studio-2008 escaping

是否有可用于转义和取消转义字符串的C#函数,可用于填充XML元素的内容?

我使用的是VSTS 2008 + C#+ .Net 3.0。

编辑1:我正在连接简单和简短的XML文件而我不使用序列化,因此我需要手动显式转义XML字符,例如,我需要将a<b放入<foo></foo> ,所以我需要转义字符串a<b并将其放入元素foo。

11 个答案:

答案 0 :(得分:116)

答案 1 :(得分:69)

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;
}

答案 2 :(得分:35)

编辑:你说“我正在连接简单和简短的XML文件,我不使用序列化,所以我需要手动显式地转义XML字符”。

强烈建议你不要手工完成。使用XML API为您完成所有操作 - 读入原始文件,将两者合并为单个文档,但您需要(可能需要使用XmlDocument.ImportNode),然后再将其写出来。您不想编写自己的XML解析器/格式化程序。序列化在这里有点无关紧要。

如果你能给我们一个简短但完整的例子来说明你正在尝试做什么,我们可以帮助你避免首先担心逃避。


原始回答

您的意思并不完全清楚,但通常XML API会为您执行此操作。您在节点中设置文本,它将自动转义它需要的任何内容。例如:

LINQ to XML示例:

using System;
using System.Xml.Linq;

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

        Console.WriteLine(element);
    }
}

DOM示例:

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);
    }
}

两个示例的输出:

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

当然,假设你想要XML转义。如果您不是,请发布更多详细信息。

答案 3 :(得分:23)

感谢@sehe的单线逃生:

var escaped = new System.Xml.Linq.XText(unescaped).ToString();

我添加了单行取消逃生:

var unescapedAgain = System.Xml.XmlReader.Create(new StringReader("<r>" + escaped + "</r>")).ReadElementString();

答案 4 :(得分:8)

乔治,这很简单。始终使用XML API来处理XML。他们为你做了所有的逃避和失败。

永远不要通过附加字符串来创建XML。

答案 5 :(得分:4)

如果你想找到这个问题,就像我一样,要逃避XML节点名称,例如从XML序列化中读取时,请使用最简单的方法:

XmlConvert.EncodeName(string nameToEscape)

它还将转义空格和XML元素的任何无效字符。

http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape%28VS.80%29.aspx

答案 6 :(得分:3)

警告:Necromancing

Still Darin Dimitrov的答案+ System.Security.SecurityElement.Escape(字符串s)还没有完成。

在XML 1.1中,最简单,最安全的方法就是对所有内容进行编码 就像\ {。1}一样。{。1} XML 1.0中根本不支持它。
对于XML 1.0,一种可能的解决方法是对包含字符的文本进行base-64编码。

&#09;

XML 1.0:

//string EncodedXml = SpecialXmlEscape("привет мир");
//Console.WriteLine(EncodedXml);
//string DecodedXml = XmlUnescape(EncodedXml);
//Console.WriteLine(DecodedXml);
public static string SpecialXmlEscape(string input)
{
    //string content = System.Xml.XmlConvert.EncodeName("\t");
    //string content = System.Security.SecurityElement.Escape("\t");
    //string strDelimiter = System.Web.HttpUtility.HtmlEncode("\t"); // XmlEscape("\t"); //XmlDecode("&#09;");
    //strDelimiter = XmlUnescape("&#59;");
    //Console.WriteLine(strDelimiter);
    //Console.WriteLine(string.Format("&#{0};", (int)';'));
    //Console.WriteLine(System.Text.Encoding.ASCII.HeaderName);
    //Console.WriteLine(System.Text.Encoding.UTF8.HeaderName);


    string strXmlText = "";

    if (string.IsNullOrEmpty(input))
        return input;


    System.Text.StringBuilder sb = new StringBuilder();

    for (int i = 0; i < input.Length; ++i)
    {
        sb.AppendFormat("&#{0};", (int)input[i]);
    }

    strXmlText = sb.ToString();
    sb.Clear();
    sb = null;

    return strXmlText;
} // End Function SpecialXmlEscape

答案 7 :(得分:2)

以下功能将完成工作。没有测试XmlDocument,但我想这要快得多。

public static string XmlEncode(string value)
{
    System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings 
    {
        ConformanceLevel = System.Xml.ConformanceLevel.Fragment
    };

    StringBuilder builder = new StringBuilder();

    using (var writer = System.Xml.XmlWriter.Create(builder, settings))
    {
        writer.WriteString(value);
    }

    return builder.ToString();
}

public static string XmlDecode(string xmlEncodedValue)
{
    System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings
    {
        ConformanceLevel = System.Xml.ConformanceLevel.Fragment
    };

    using (var stringReader = new System.IO.StringReader(xmlEncodedValue))
    {
        using (var xmlReader = System.Xml.XmlReader.Create(stringReader, settings))
        {
            xmlReader.Read();
            return xmlReader.Value;
        }
    }
}

答案 8 :(得分:1)

使用第三方库(Newtonsoft.Json)作为替代:

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

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

示例:

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

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

答案 9 :(得分:1)

根据约翰·斯基特(John Skeet)的回答的另一种说法,即不返回标签

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

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

这仅返回传入的值,采用XML编码格式:

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

答案 10 :(得分:-1)

SecurityElementEscape 为您完成这项工作

在 SecurityElement 中使用字符串之前,使用此方法替换字符串中的无效字符。如果在 SecurityElement 中使用了无效字符而不进行转义,则会引发 ArgumentException。

下表显示了无效的 XML 字符及其转义的等效字符。

enter image description here

https://docs.microsoft.com/en-us/dotnet/api/system.security.securityelement.escape?view=net-5.0