最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#按路徑流式遍歷XML節(jié)點的實用方法

 更新時間:2025年10月30日 09:51:08   作者:貪嘴  
在處理大型 XML 文檔時,傳統(tǒng)的 XDocument.Load 會一次性將整個文檔加載到內存中,對于大文件非常消耗資源,本文將分享一個按路徑流式遍歷 XML 節(jié)點的實用方法,支持深層嵌套路徑,并保持流式解析,需要的朋友可以參考下

引言

在處理大型 XML 文檔時,傳統(tǒng)的 XDocument.Load 會一次性將整個文檔加載到內存中,對于大文件非常消耗資源。尤其在只需要部分節(jié)點的場景下,這種方式既浪費內存,又影響性能。

本文將分享一個按路徑流式遍歷 XML 節(jié)點的實用方法,支持深層嵌套路徑,并保持流式解析,內存占用低,非常適合大文件處理。

方法原理

流式解析

使用 XmlReader 逐節(jié)點讀取 XML 文檔,而不是一次性加載整個文檔,節(jié)省內存。

按路徑過濾節(jié)點

用戶只需提供路徑,例如 "set/fields/field",方法會按照路徑遞歸查找目標元素。

XNode.ReadFrom 創(chuàng)建完整 XElement

當讀到目標元素時,使用 XNode.ReadFrom(reader) 構建 XElement,包括子節(jié)點及結束標簽,并將 XmlReader 定位到下一個兄弟節(jié)點,保證流式遍歷不中斷。

遞歸獲取子節(jié)點

對于多級路徑,使用遞歸方法從 XElement 訪問子節(jié)點

使用示例

假設有如下 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");

Console.WriteLine("字段數(shù)量:" + fields.Count());
foreach (var f in fields)
{
    Console.WriteLine(f.Element("fieldname")?.Value);
}

輸出:

字段數(shù)量:2
rq
djbh

優(yōu)點總結

  1. 內存占用低:大 XML 文件也能按需遍歷,不會一次性加載整個文檔。
  2. 路徑靈活:支持任意深度路徑,按需獲取節(jié)點。
  3. 避免 ReadSubtree 陷阱:使用 XNode.ReadFrom 與遞歸子節(jié)點,狀態(tài)管理清晰。
  4. 延遲執(zhí)行:返回 IEnumerable<XElement>,可以直接在 foreach 中流式消費。

擴展思路

  1. 可以在路徑中增加通配符 * 或 //,支持 XPath-like 查找。
  2. 可以結合 yield return,實現(xiàn)大文件邊解析邊處理,適合數(shù)據(jù)清洗、日志分析、報表導出等場景。

完整代碼

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 節(jié)點,路徑用 / 分隔
    /// </summary>
    /// <param name="xmlstr">XML 字符串</param>
    /// <param name="xpath">節(jié)點路徑,例如 "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();

    if (nodes.Length == 1)
    {
        if (XNode.ReadFrom(reader) is XElement el)
        {
            foreach (var e in el.Elements(xpath))
            {
                yield return e;
            }
        }
    }
    else
    {
        while (reader.Read())
        {
            if (reader.NodeType != XmlNodeType.Element) continue;

            if (reader.Name == nodes[0] && XNode.ReadFrom(reader) is XElement el)
            {
                foreach (var child in GetElementsRecursive(el, nodes, 1))
                    yield return child;
            }
        }
    }
}

    /// <summary>
    /// 遞歸獲取子節(jié)點
    /// </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);
    }
}

到此這篇關于C#按路徑流式遍歷XML節(jié)點的實用方法的文章就介紹到這了,更多相關C#流式遍歷XML節(jié)點內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

城口县| 宁安市| 五家渠市| 永新县| 陆良县| 新野县| 武川县| 垫江县| 饶平县| 青神县| 溧水县| 道真| 水城县| 潍坊市| 尚志市| 苍梧县| 兴安县| 石泉县| 正阳县| 新野县| 富顺县| 外汇| 洞口县| 惠东县| 禄丰县| 鄂伦春自治旗| 且末县| 马尔康县| 西林县| 漳浦县| 清流县| 界首市| 嘉义县| 商城县| 天台县| 北辰区| 娄底市| 惠来县| 健康| 茌平县| 广灵县|