C# 字符串转义为 XML

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1132494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:59:03  来源:igfitidea点击:

String escape into XML

c#.netxmlvisual-studio-2008escaping

提问by George2

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?

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

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

我使用的是 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<binto <foo></foo>, so I need escape string a<band put it into element foo.

编辑1:我是串联简单和短期的XML文件,我不使用序列化,所以我需要手动明确转义XML字符,例如,我需要把a<b<foo></foo>,所以我需要逃避串a<b并付诸元素富。

采纳答案by Darin Dimitrov

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

回答by Jon Skeet

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".

编辑:您说“我正在连接简单而简短的 XML 文件,并且我不使用序列化,因此我需要手动显式转义 XML 字符”。

I would stronglyadvise 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.

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

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:

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

LINQ to XML example:

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 example:

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

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.

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

回答by John Saunders

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

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

Never create XML by appending strings.

切勿通过附加字符串来创建 XML。

回答by Ramazan Binarbasi

Following functions will do the work. Didn't test against XmlDocument, but I guess this is much faster.

以下功能将完成工作。没有针对 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;
        }
    }
}

回答by Keith Robertson

Thanks to @sehe for the one-line escape:

感谢@sehe 的单行转义:

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

I add to it the one-line un-escape:

我添加了一行 un-escape:

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

回答by CharlieBrown

And if you want, like me when I found this question, to escape XML node names, like for example when reading from an XML serialization, use the easiest way:

如果你想,像我发现这个问题时一样,转义 XML 节点名称,例如从 XML 序列化读取时,使用最简单的方法:

XmlConvert.EncodeName(string nameToEscape)

It will also escape spaces and any non-valid characters for XML elements.

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

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

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

回答by Stefan Steiger

WARNING: Necromancing

警告:死灵法术

Still Darin Dimitrov's answer + System.Security.SecurityElement.Escape(string s) isn't complete.

Darin Dimitrov 的回答 + System.Security.SecurityElement.Escape(string s) 仍然不完整。

In XML 1.1, the simplest and safest way is to just encode EVERYTHING.
Like &#09;for \t.
It isn't supported at all in XML 1.0.
For XML 1.0, one possible workaround is to base-64 encode the text containing the character(s).

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

//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

XML 1.0:

XML 1.0:

public static string Base64Encode(string plainText)
{
    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
    return System.Convert.ToBase64String(plainTextBytes);
}

public static string Base64Decode(string base64EncodedData)
{
    var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
    return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}

回答by abberdeen

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

使用第三方库 ( 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();
}

Example:

例子:

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

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

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

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

回答by Rick Strahl

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

另一种基于 John Skeet 的答案的方法,该答案不返回标签

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:

这仅以 XML 编码格式返回传入的值:

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