理想情况下,在您的代码使用它之前,XML 会被正确转义。如果这超出了您的控制范围,您可以编写一个正则表达式。除非您绝对确定值不包含其他转义项,否则不要使用 String.Replace 方法。
例如,"wow&".Replace("&", "&") 会导致 wow&,这显然是不可取的。
Regex.Replace 可以为您提供更多控制以避免这种情况,并且可以编写为仅匹配不属于其他字符的“&”符号,例如<,例如:
string result = Regex.Replace(test, "&(?!(amp|apos|quot|lt|gt);)", "&");
上述方法有效,但不可否认,它不包括以 & 符号开头的各种其他字符,例如  ,并且列表可能会增加。
更灵活的方法是解码 value 属性的内容,然后重新编码。如果您有value="&wow&",则解码过程将返回"&wow&",然后重新编码将返回"&wow&",这是可取的。要做到这一点,你可以使用这个:
string result = Regex.Replace(test, @"value=\""(.*?)\""", m => "value=\"" +
HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(m.Groups[1].Value)) +
"\"");
var doc = XElement.Parse(result);
请记住,上面的正则表达式只针对 value 属性的内容。如果 XML 结构中的其他区域存在相同的问题,则可以对其进行调整以匹配它们并以类似的方式替换它们的内容。
编辑: 更新的解决方案应该处理标签之间的内容以及双引号之间的任何内容。请务必彻底测试。尝试使用正则表达式操作 XML/HTML 标记是不利的,因为它容易出错且过于复杂。您的情况有些特殊,因为您需要先对其进行消毒才能使用它。
string pattern = "(?<start>>)(?<content>.+?(?<!>))(?<end><)|(?<start>\")(?<content>.+?)(?<end>\")";
string result = Regex.Replace(test, pattern, m =>
m.Groups["start"].Value +
HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(m.Groups["content"].Value)) +
m.Groups["end"].Value);
var doc = XElement.Parse(result);