Оценка элемента итерации в c # для очень больших XML-файлов - PullRequest
0 голосов
/ 01 ноября 2018

Я работаю с множеством различных 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-файл в xmldocument из этой схемы generate и xsd и найти из нее первый maxOccurs с подэлементами внутри него. Это прекрасно работает, но использование xmldocument не очень хорошо работает с очень большими XML-файлами (gb-size).

Для этого мне нужно использовать xmlreader, но я понятия не имею, как я могу приблизиться к оценке итератора с xmlreader, так как я не могу использовать трюк xsd.

Итак, ищите информацию о том, как ее оценить, любые идеи приветствуются

1 Ответ

0 голосов
/ 01 ноября 2018

Попробуйте следующий код, который помещает результаты в словарь

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();
            }
        }
    }

}
...