理想情况下,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);