

新闻资讯
技术教程使用宽容模式解析不规范XML,结合XmlReader设置与HtmlAgilityPack,预处理清洗数据并防御性提取关键内容。
处理格式不规范的XML是实际开发中常遇到的问题,尤其在对接第三方系统或读取老旧数据时。C# 提供了多种方式来解析 XML,但在面对标签未闭合、属性缺失引号、编码错误等混乱情况时,默认解析器容易抛出异常。这时候需要启用“宽容模式”并结合合适的方法提取有效数据。
标准的 XmlDocument 和 XDocument 在遇到非法 XML 时会直接报错,但 XmlReader 允许通过设置 XmlReaderSettings 来放宽验证规则。
虽然 .NET 原生并不支持像 HTML 解析器那样的完全容错(如 AngleSharp 或 HtmlAgilityPack),但可以配合外部库或调整输入提升鲁棒性。
CheckCharacters = false 忽略非法字符ValidateOnParse = false 防止 DTD 验证中断解析IgnoreWhitespace = true 减少因空格导致的结构误判// 示例:创建宽容的 XmlReader
var settings = new XmlReaderSettings
{
CheckCharacters = false
,
ValidateOnParse = false,
IgnoreWhitespace = true,
IgnoreComments = true,
IgnoreProcessingInstructions = true
};
using var reader = XmlReader.Create(streamOrPath, settings);
var doc = new XmlDocument();
doc.Load(reader); // 尽量加载可识别部分
当 XML 混乱到接近 HTML 的程度(例如标签不闭合、嵌套错误),推荐使用 HtmlAgilityPack —— 它专为容忍语法错误而设计,也能用于非标准 XML。
// 示例:用 HtmlAgilityPack 加载破损 XML
var htmlDoc = new HtmlAgilityPack.HtmlDocument(); htmlDoc.OptionFixNestedTags = true; // 自动修复嵌套 htmlDoc.OptionAutoCloseOnEnd = true; // 遇到结束标签自动补全 htmlDoc.OptionCheckSyntax = false; htmlDoc.Load(filePath); // 即使格式错误也能读入// 使用类似 XPath 的方式提取数据 var nodes = htmlDoc.DocumentNode.SelectNodes("//item"); foreach (var node in nodes) { var id = node.GetAttributeValue("id", ""); var name = node.SelectSingleNode("name")?.InnerText.Trim(); Console.WriteLine($"{id}: {name}"); }
在解析前对原始文本做简单清洗,能显著提高成功率。
& 为 & 防止实体解析失败
)规范化为
// 清洗示例
string CleanXmlString(string input)
{
// 移除非法 XML 字符
var cleaned = Regex.Replace(input, @"[\x00-\x08\x0B\x0C\x0E-\x1F]", "");
// 修复孤立的 &
cleaned = Regex.Replace(cleaned, @"&(?![a-zA-Z#][a-zA-Z0-9#]*;)", "&");
// 补全常见自闭合标签(视需求扩展)
cleaned = Regex.Replace(cleaned, @"<(img|br|hr|input|meta|link)\b([^>]*)>",
@"<$1$2 />");
return cleaned;}
灵活提取与容错处理
即使成功加载文档,某些节点仍可能为空或结构异常。编写数据提取逻辑时应保持防御性。
基本上就这些。面对混乱 XML,关键是不要依赖严格标准,而是组合使用宽容读取、外部解析库和前置清洗,把“能救的数据”尽可能捞出来。很多时候不需要完美还原,只要关键字段可用即可。