为非常大的 xml 文件估计 c# 中的迭代元素

Posted

技术标签:

【中文标题】为非常大的 xml 文件估计 c# 中的迭代元素【英文标题】:Estimating the iteration element in c# for very large xml files 【发布时间】:2019-04-05 10:49:32 【问题描述】:

我正在处理大量不同的 xml 文件,我不知道文件中的迭代元素。

我所说的迭代元素是指在整个 xml 文件中重复的元素(在 xsd-fiels 中也可以看到为 maxOccurs="unbounded")。

例如,订单文件可能包含名为 order 的重复元素

我收到的一些结构示例是

<order>
   <order>...</order>
   <order>...</order>
</orders>

<products>
   <product>...</product>
   <product>...</product>
</products>

<root>
   <element>...</element>
   <element>...</element>
</root>

<products>
   <section>
    <someelement>content</someelement>
    <item>...</item>
    <item>...</item>
    <item>...</item>
    <item>...</item>
   </section>
</products>

在上面的例子中,迭代器/中继器被称为:

orders > order
products > product
root > element
products > section > item

我估计迭代器的常用方法是将完整的 xml 文件加载到该 generate 和 xsd 模式中的 xmldocument 中,并从中找到第一个 maxOccurs 以及其中的子元素。 这很好用,但使用 xmldocument 不适用于非常大的 xml 文件(gb 大小)。

对于这些我需要使用 xmlreader,但我不知道如何使用 xmlreader 来估计迭代器,因为我不能使用 xsd 技巧。

所以寻找有关如何估计它的输入,任何想法都表示赞赏

【问题讨论】:

请格式化您的xml代码 更新了,现在清楚了吗? 嗯,我实际上是指缩进或缺少... 这是规范/需求问题,不是编码问题。如果您可以提供“迭代”元素的含义的精确规范,那么对该规范进行编码将很容易。挑战在于您所描述的概念是一个非常模糊的概念,并且有许多 XML 文档不适用于它。例如,在一篇科学文章中,您会查找章节还是段落? 我通常面临的复杂程度如上所述,正如我所写,我选择第一个 maxoccurs = unbound。这是我的世界中的编码问题 【参考方案1】:

尝试以下将结果放入字典的代码

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;


namespace ConsoleApplication75

    class Program
    
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        
            Node.ParseChildren(FILENAME);
        


    
    public class Node
    
        public static XmlReader reader;
        public static Dictionary<string, int> dict = new Dictionary<string, int>();

        public static void ParseChildren(string filename)
        
            reader = XmlReader.Create(filename);
            reader.MoveToContent();
            string name = "";
            reader.ReadStartElement();
            ParseChildrenRecursive(name);
        

        public static void ParseChildrenRecursive(string path)
        
            while (!reader.EOF)
            
                if (reader.NodeType == XmlNodeType.EndElement)
                
                    reader.ReadEndElement();
                    break;
                
                if (reader.IsStartElement())
                
                    string childName = reader.LocalName;
                    string newPath = path + " > " + childName;
                    if(dict.ContainsKey(newPath))
                    
                        dict[newPath] += 1;
                    
                    else
                    
                        dict.Add(newPath, 1);
                    
                    reader.ReadStartElement();
                    ParseChildrenRecursive(newPath);
                
                if ((reader.NodeType != XmlNodeType.StartElement) && (reader.NodeType != XmlNodeType.EndElement))
                   reader.Read();
            
        
    


【讨论】:

最后一条语句可能正在读取开始或结束元素 (reader.Read();),因此您可能只想在它不是结束元素时阅读。 if ((reader.NodeType != XmlNodeType.StartElement) && (reader.NodeType != XmlNodeType.EndElement) ) reader.Read();

以上是关于为非常大的 xml 文件估计 c# 中的迭代元素的主要内容,如果未能解决你的问题,请参考以下文章

Python3迭代器与生成器

Python3 迭代器与生成器

非线性方程(组):一维非线性方程插值迭代方法 [MATLAB]

详解C# 迭代器

如何搜索 xml 节点值,然后在 c# 中为该元素创建新属性

使用 LINQ - C# 在 xml 文件中的特定节点下方添加新元素