是否有任何 C# 函数可用于转义和取消转义字符串,该字符串可用于填充 XML 元素的内容?
我正在使用 VSTS 2008 + C# + .Net 3.0。
编辑1:我正在连接简单而短的XML文件,并且不使用序列化,所以我需要手动显式转义XML字符,例如,我需要将
a<b
放入<foo></foo>
,所以我需要转义字符串a<b
并将其放入元素foo中。
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;
}
编辑:你说“我正在连接简单而短的 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 & stuff <></tag>
当然,这是假设您想要 XML 转义。如果不是,请发布更多详细信息。
感谢@sehe 的一行转义:
var escaped = new System.Xml.Linq.XText(unescaped).ToString();
我添加了一行取消转义:
var unescapedAgain = System.Xml.XmlReader.Create(new StringReader("<r>" + escaped + "</r>")).ReadElementString();
乔治,这很简单。始终使用 XML API 来处理 XML。他们为你做了所有的逃避和解除逃避。
切勿通过附加字符串来创建 XML。
如果您像我发现这个问题时一样想要转义 XML 节点名称,例如从 XML 序列化读取时,请使用最简单的方法:
XmlConvert.EncodeName(string nameToEscape)
它还会转义 XML 元素的空格和任何无效字符。
http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape%28VS.80%29.aspx
基于 John Skeet 的回答的另一种做法是 不返回标签:
void Main()
{
XmlString("Brackets & stuff <> and \"quotes\"").Dump();
}
public string XmlString(string text)
{
return new XElement("t", text).LastNode.ToString();
}
这仅返回传入的值,采用 XML 编码格式:
Brackets & stuff <> and "quotes"
警告:死灵术
Darin Dimitrov 的答案 + System.Security.SecurityElement.Escape(string s) 仍然不完整。
在 XML 1.1 中,最简单、最安全的方法就是对所有内容进行编码。
喜欢
	
的 .//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("	");
//strDelimiter = XmlUnescape(";");
//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:
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);
}
以下功能将完成这项工作。没有针对 XmlDocument 进行测试,但我想这要快得多。
using System.IO;
using System.Xml;
public static string XmlEncode(string value)
{
var settings = new XmlWriterSettings
{
ConformanceLevel = ConformanceLevel.Fragment
};
var builder = new StringBuilder();
using (var writer = XmlWriter.Create(builder, settings))
writer.WriteString(value);
return builder.ToString();
}
public static string XmlDecode(string xmlEncodedValue)
{
var settings = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment
};
using var stringReader = new StringReader(xmlEncodedValue);
using var xmlReader = XmlReader.Create(stringReader, settings);
xmlReader.Read();
return xmlReader.Value;
}
使用第三方库(Newtonsoft.Json)作为替代:
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();
}
转义字符串示例:
a<b
==>"a<b"
<foo></foo>
==>"foo></foo>"
注意: 在较新的版本中,上面编写的代码可能无法使用转义,因此您需要指定字符串将如何转义:
public static string XmlEscape(string unescaped)
{
if (unescaped == null) return null;
return JsonConvert.SerializeObject(unescaped, new JsonSerializerSettings()
{
StringEscapeHandling = StringEscapeHandling.EscapeHtml
});
}
转义字符串示例:
a<b
==>"a\u003cb"
<foo></foo>
==>"\u003cfoo\u003e\u003c/foo\u003e"
SecurityElementEscape 为您完成这项工作
在 SecurityElement 中使用字符串之前,使用此方法替换字符串中的无效字符。如果在 SecurityElement 中使用无效字符而不进行转义,则会引发 ArgumentException。
下表显示了无效的 XML 字符及其转义等效字符。
https://learn.microsoft.com/en-us/dotnet/api/system.security.securityelement.escape?view=net-5.0