xelement.parse用于解析xml字符串,xelement.load用于从io源(如文件、流)加载xml;误用load解析字符串会报错;parse默认禁用dtd,load默认启用,存在xxe风险;parse校验严格,load对空流等处理较模糊;parse性能略高但不可复用,load配合xmlreader可优化批量解析。

Parse 是从字符串直接解析,Load 是从流/文件等 IO 源读取
XElement.Parse 只接受 string 类型输入,内部用 XmlReader.Create(new StringReader(xmlString)) 包一层后解析;XElement.Load 接收的是 Stream、TextReader、XmlReader 或文件路径 string(此时会自动按路径打开文件流)。传入纯 XML 字符串却误用 Load,会触发 DirectoryNotFoundException 或 XmlException —— 因为它真去当文件路径找了。
- 想解析拼出来的 XML 字符串(比如 API 返回体、模板替换结果),必须用
Parse - 要从磁盘文件、HTTP 响应流、
MemoryStream读 XML,优先用Load -
Load("data.xml")中的参数是路径,不是内容;Parse("<root></root>")中的参数才是内容
Load 传字符串路径时默认启用 DTD 解析,Parse 默认禁用
这是最容易被忽略的安全与性能差异。.NET Framework 下 Load(string) 内部创建 XmlReader 时用的是默认设置,DtdProcessing 为 Parse,意味着会尝试加载外部 DTD;而 Parse(string) 使用的是更保守的 XmlReaderSettings,DtdProcessing 默认为 Ignore。如果 XML 含 ,用 <code>Load 读网络不可信字符串(比如用户上传的文件名拼成路径)可能引发 XXE 攻击或 DNS 外泄。
- 若必须用
Load读字符串内容,请显式传XmlReader并设settings.DtdProcessing = DtdProcessing.Ignore - 对不可信输入,宁可用
Parse+ 手动构造StringReader,也不要用Load碰路径字符串 - .NET Core / .NET 5+ 默认都禁用 DTD,但行为一致性仍建议显式控制
空字符串、null、BOM 和编码问题在 Parse 和 Load 中表现不同
Parse 对输入字符串做零容忍校验:传 null 直接抛 ArgumentNullException;传空字符串或只含空白,会报 XmlException:“根元素缺失”。Load 在读流时更“宽容”一点——比如传空 MemoryStream,会卡在读取首字节就崩;但若文件存在却为空,错误信息是“意外的 EOF”,不如 Parse 明确。
-
Parse("\ufeff<root></root>")(带 UTF-8 BOM 的字符串)会失败,因为\ufeff不是合法 XML 开头;需先用Encoding.UTF8.GetString(bytes)正确解码再传 -
Load(stream)能自动识别 UTF-8/UTF-16 BOM,但Load(stringPath)依赖系统默认编码(如 Windows 上是 ANSI),易乱码 - 统一推荐:可信字符串走
Parse;不确定来源的二进制数据,先用XmlReader.Create(stream, settings)配好编码和 DTD 策略,再喂给XElement.Load
性能上 Parse 更轻量,但反复调用要注意字符串分配
Parse 没 IO 开销,纯内存解析,单次调用比 Load 快 10%–20%;但它每次都会新建 StringReader 和 XmlReader,如果高频解析小 XML(如日志字段、配置片段),字符串拼接 + Parse 可能造成 GC 压力。而 Load(XmlReader) 形式可复用 XmlReader 实例(需重置流位置),适合循环解析多个 XML 片段。
- 简单场景(一次一串):用
Parse,干净利落 - 批量处理(如解析 JSON 数组里每个 item 的嵌入 XML 字段):预建
XmlReader+Load,避免重复初始化开销 - 别为了“省一次 new”把字符串缓存起来长期持有,XML 字符串通常不值得常驻内存










