当前位置: 首页 > news >正文

使用 C# 流式解析 超大XML:按路径遍历子节点的实用方法


使用 C# 流式解析 XML:按路径遍历子节点的实用方法

在处理大型 XML 文档时,传统的 XDocument.Load 会一次性将整个文档加载到内存中,对于大文件非常消耗资源。尤其在只需要部分节点的场景下,这种方式既浪费内存,又影响性能。

本文将分享一个按路径流式遍历 XML 节点的实用方法,支持深层嵌套路径,并保持流式解析,内存占用低,非常适合大文件处理。


方法原理

  1. 流式解析

    使用 XmlReader 逐节点读取 XML 文档,而不是一次性加载整个文档,节省内存。

  2. 按路径过滤节点

    用户只需提供路径,例如 "set/fields/field",方法会按照路径递归查找目标元素。

  3. XNode.ReadFrom 创建完整 XElement

    当读到目标元素时,使用 XNode.ReadFrom(reader) 构建 XElement,包括子节点及结束标签,并将 XmlReader 定位到下一个兄弟节点,保证流式遍历不中断。

  4. 递归获取子节点

    对于多级路径,使用递归方法从 XElement 访问子节点


使用示例

假设有如下 XML:

<set><fields><field><fieldname>rq</fieldname><datatype>字符</datatype></field><field><fieldname>djbh</fieldname><datatype>字符</datatype></field></fields>
</set>

调用:

string xmlstr = File.ReadAllText("example.xml");var fields = XmlStreamHelper.StreamElements(xmlstr, "set/fields/field").ToList();Console.WriteLine("字段数量:" + fields.Count);
foreach (var f in fields)
{Console.WriteLine(f.Element("fieldname")?.Value);
}

输出:

字段数量:2
rq
djbh

优点总结

  1. 内存占用低:大 XML 文件也能按需遍历,不会一次性加载整个文档。
  2. 路径灵活:支持任意深度路径,按需获取节点。
  3. 避免 ReadSubtree 陷阱:使用 XNode.ReadFrom 与递归子节点,状态管理清晰。
  4. 延迟执行:返回 IEnumerable<XElement>,可以直接在 foreach 中流式消费。

扩展思路

  1. 可以在路径中增加通配符 *//,支持 XPath-like 查找。
  2. 可以结合 yield return,实现大文件边解析边处理,适合数据清洗、日志分析、报表导出等场景。

完整代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;public static class XmlStreamHelper
{/// <summary>/// 按路径流式遍历 XML 节点,路径用 / 分隔/// </summary>/// <param name="xmlstr">XML 字符串</param>/// <param name="xpath">节点路径,例如 "set/fields/field"</param>public static IEnumerable<XElement> StreamElements(string xmlstr, string xpath){if (string.IsNullOrWhiteSpace(xmlstr) || string.IsNullOrWhiteSpace(xpath))yield break;var nodes = xpath.Split('/');using var reader = XmlReader.Create(new StringReader(xmlstr), new XmlReaderSettings { IgnoreWhitespace = true, IgnoreComments = true });reader.MoveToContent();while (reader.Read()){if (reader.NodeType != XmlNodeType.Element) continue;if (nodes.Length == 1){if (reader.Name == nodes[0] && XNode.ReadFrom(reader) is XElement el)yield return el;}else if (reader.Name == nodes[0] && XNode.ReadFrom(reader) is XElement el){foreach (var child in GetElementsRecursive(el, nodes, 1))yield return child;}}}/// <summary>/// 递归获取子节点/// </summary>private static IEnumerable<XElement> GetElementsRecursive(XElement el, string[] nodes, int index){if (index == nodes.Length - 1)return el.Elements(nodes[index]);var sub = el.Element(nodes[index]);return sub == null ? Enumerable.Empty<XElement>() : GetElementsRecursive(sub, nodes, index + 1);}
}

http://www.dtcms.com/a/529923.html

相关文章:

  • 网站建设 成都上海网站建设就q479185700顶上
  • 中小企业网站制作广州网络服务公司找赛合公司点个赞科技 网站制作
  • 网站建设 全是乱码百度一下你就知道官网网页版
  • 网站域名注册证明wordpress页面布局插件
  • Java 项目 — 五种创建方式
  • 可以做推文的网站为何公司做的网站很丑
  • 宜春网站开发公司电话可以用来展示的网站
  • custed谁做的网站商品详情页设计模板
  • 【开题答辩全过程】以 布哩民宿预定系统的设计与实现为例,包含答辩的问题和答案
  • 不到网站是为什么深圳开发微信公众号
  • 网站基础建设一般多少钱自己做网站的服务器
  • 平台网站模板素材图片网页设计与网站开发项目
  • 专业建网站平台电商网站需要哪些备案
  • 网站设计维护内容asp.net 网站管理工具 安全
  • AUTOSAR AP通信管理规范:设计背景与技术实现解析
  • 网上订餐网站模板wordpress如何加html
  • 【开发者导航】高性能跨平台数据整理与分析工具:qsv让CSV处理更高效
  • 佛山市网站建设 乾图信息科技一 网站建设方案
  • 毕业设计做视频网站江苏建设部网站
  • 成都企业网站备案流程dede 网站目录
  • Spring Boot3零基础教程,Mybatis 自动配置解析,笔记53
  • 俄语网站里做外贸shop中国对外建设有限公司网站
  • 南昌网站设计公司哪家好石家庄新闻频道
  • 二叉树问题讨论(部分内容待补充)
  • uniapp本地打包详细教程
  • 做国外网站手机端网站的区别
  • 新网站开发费用参加sem培训
  • alexa怎么查询网站排名程序员都需要学什么
  • 长江工程建设局网站珠海做网站推广公司
  • 专业微网站建设百度mip wordpress