我正在尝试在.NET(C#)中的字符串中删除XML实体,但我似乎无法使其正常工作。
例如,如果我有字符串AT&T
,则应将其翻译为AT&T
。
一种方法是使用HttpUtility.HtmlDecode(),但这是针对HTML的。
所以我有两个问题:
使用HttpUtility.HtmlDecode()解码XML实体是否安全?
如何使用XmlReader(或类似的东西)来执行此操作?我尝试了以下内容,但总是返回一个空字符串:
static string ReplaceEscapes(string text)
{
StringReader reader = new StringReader(text);
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader xmlReader = XmlReader.Create(reader, settings))
{
return xmlReader.ReadString();
}
}
答案 0 :(得分:13)
HTML转义和XML密切相关。正如您所说,HttpUtility
同时包含HtmlEncode
和HtmlDecode
方法。这些也将对XML进行操作,因为只有少数实体需要转义:两个HTML中都有<
,>
,\
,'
和&
和XML。
使用HttpUtility
类的缺点是你需要引用System.Web
dll,这也带来了许多你可能不想要的东西。
特别是对于XML,SecurityElement
类有一个Escape
方法可以进行编码,但没有相应的Unescape
方法。因此,您有几个选择:
HttpUtility.HtmlDecode()
并提及对System.Web
滚动你自己的解码方法来处理特殊字符(因为只有少数 - 在Reflector中查看SecurityElement
的静态构造函数以查看完整列表)
使用(hacky)解决方案,如:
public static string Unescape(string text)
{
XmlDocument doc = new XmlDocument();
string xml = string.Format("<dummy>{0}</dummy>", text);
doc.LoadXml(xml);
return doc.DocumentElement.InnerText;
}
就个人而言,如果我已经引用了HttpUtility.HtmlDecode()
,我会使用System.Web
,如果没有,我会使用自己的XmlReader
。我不喜欢你的Disposable
方法,因为它是{{1}},它通常表明它正在使用需要处理的资源,因此可能是一项代价高昂的操作。
答案 1 :(得分:8)
您的#2解决方案可行,但您需要在xmlReader.Read();
之前致电xmlReader.MoveToContent();
(或ReadString
)。
我认为#1也是可以接受的,即使像®
这样的边缘情况是有效的HTML实体,但不是XML实体 - 你的unescaper应该怎么做呢?将异常作为正确的XML解析器抛出,或者只是像HTML解析器那样返回“®”?
答案 2 :(得分:1)
这有效:
using (XmlReader xmlReader = XmlReader.Create(reader, settings))
{
if (xmlReader.Read())
{
return xmlReader.ReadString();
}
}
答案 3 :(得分:1)
如果您的输入文字以某些空白字符结尾(如回车),我发现最常见的答案有一个小错误。
字符串“Testing&amp;#10;”失去它的尾随空白。
如果你将问题中的解决方案与adrianbanks的包装标签结合起来,你会得到以下信息,这是有效的。
public static string UnescapeUnicode(string line)
{
using (StringReader reader = new StringReader("<a>" + line + "</a>"))
{
using (XmlReader xmlReader = XmlReader.Create(reader))
{
xmlReader.MoveToContent();
return xmlReader.ReadElementContentAsString();
}
}
}
答案 4 :(得分:0)
这也有效,并且代码最少:
public static string DecodeString(string encodedString)
{
if (string.IsNullOrEmpty(formattedText))
return string.Empty;
XmlTextReader xtr = new XmlTextReader(encodedString, XmlNodeType.Element, null);
if (xtr.Read())
return xtr.ReadString();
throw new Exception("Error decoding xml string : " + encodedString);
}
Update1:嗯,如果encodeString是&#34;&#34;,那么xtr.Read()返回false,它似乎不起作用。
Update2:添加了解决方法
Update3:这似乎工作得更好
public static string DecodeString(string encodedString)
{
XmlTextReader xtr = new XmlTextReader(encodedString, XmlNodeType.Element, null);
xtr.MoveToContent();
return xtr.Value;
}