Очень поздно здесь, но я хочу поделиться своим решением, которое обрабатывает случаи, когда у вас есть и & (неверный xml) и & (действительный xml) в документе в дополнение к другим символам xml.
Это решение предназначено только для случаев, когда вы не можете управлять генерацией XML, как правило, потому что это происходит из какого-то внешнего источника. Если вы управляете генерацией xml, пожалуйста, используйте XmlTextWriter, как предложено @Justin Niessner
Это также довольно быстро и обрабатывает все различные сущности / ссылки на символы XML
Предопределенные символьные объекты:
& quot;
& amp;
'
& lt;
& gt;
Числовые символьные объекты / ссылки:
& #nnnn;
& #xhhhh;
PS! Пробел после & не должен быть включен в сущности / ссылки, я просто добавил его здесь, чтобы избежать его кодирования при визуализации страницы
Код
public static string CleanXml(string text)
{
int length = text.Length;
StringBuilder stringBuilder = new StringBuilder(length);
for (int i = 0; i < length; ++i)
{
if (text[i] == '&')
{
var remaining = Math.Abs(length - i + 1);
var subStrLength = Math.Min(remaining, 12);
var subStr = text.Substring(i, subStrLength);
var firstIndexOfSemiColon = subStr.IndexOf(';');
if (firstIndexOfSemiColon > -1)
subStr = subStr.Substring(0, firstIndexOfSemiColon + 1);
var matches = Regex.Matches(subStr, "&(?!quot;|apos;|amp;|lt;|gt;|#x?.*?;)|'");
if (matches.Count > 0)
stringBuilder.Append("&");
else
stringBuilder.Append("&");
}
else if (XmlConvert.IsXmlChar(text[i]))
{
stringBuilder.Append(text[i]);
}
else if (i + 1 < length && XmlConvert.IsXmlSurrogatePair(text[i + 1], text[i]))
{
stringBuilder.Append(text[i]);
stringBuilder.Append(text[i + 1]);
++i;
}
}
return stringBuilder.ToString();
}