Могу ли я сериализовать большие XML-файлы в двоичный формат и все еще иметь возможность использовать XPath? - PullRequest
1 голос
/ 06 мая 2011

** Краткое пояснение ** В моей программе C # WinForms у меня есть 2 TreeView (они работают как ListView, поэтому они не являются вложенными) и 1 ListView.Я заполняю первый TreeView данными из некоторых XML-файлов (имя файла как свойство TreeNode.Text, а TreeNode.Name будет содержать путь к XML-файлу).

Первый TreeView: когда пользователь нажимает на любой узел,второй TreeView заполнится некоторыми данными из файла XML.

Второй TreeView: когда пользователь щелкает по любому узлу, снова некоторые данные из файла XML будут отображаться в ListView.

ListView: Когда пользователь нажимает на любой элемент, снова отображаются некоторые данные из XML-файла (в моем случае это координаты кривой, которую я рисую на PictureBox).

** Визуализация ** ОченьКраткий пример моих XML-файлов:

<XML>
   <Group Name="IO">

     <PIN Name="IO1">
        <PAIR>
          <Voltage>-3</Voltage>
          <Current>-3</Current>
        </PAIR>
        <PAIR>
          <Voltage>3</Voltage>
          <Current>-3</Current>
        </PAIR>
      </PIN>

     <PIN Name="IO2">
        <PAIR>
          <Voltage>-3</Voltage>
          <Current>-3</Current>
        </PAIR>
        <PAIR>
          <Voltage>3</Voltage>
          <Current>-3</Current>
        </PAIR>
      </PIN>

    </Group>

    <Group Name="PWR">
 ///and so on
    </Group>
 </XML>

Итак, моя идея такова: поскольку мои XML-файлы иногда очень большие (более 10 МБ), с ними очень медленно справляться.Интересно, есть ли способ преобразовать их в двоичный файл и работать с подобными командами, такими как 'XPATH' и 'XmlDocument' с этим двоичным файлом?

1 Ответ

2 голосов
/ 06 мая 2011

Сериализация его как двоичного не должна быть проблемой - на самом деле, это будет идеальный сценарий для protobuf-net, так как это дерево-сериализатор (например, XmlSerializer), и можетдаже работать с XmlElementAttribute s, если вы действительно хотите (так что вам не нужно больше декорирование).

Однако большинство сериализаций не позволяют фильтровать (и т. д.) файл, пока он простофайл - вам нужно будет перекомпилировать объектную модель в обычную объектную модель и работать с этим.К счастью, с таким быстрым двоичным сериализатором, как бы то ни было, он должен быть быстрее загружаться (и намного меньше, чем 10 МБ).

Однако другой жизнеспособный вариант - использовать встроенную базу данных и записывать данные в виде записей вструктура индексированной таблицы, которая поддерживает запросы, которые вам необходимы.

Для получения информации, быстрый тест с вашими примерами данных показал, что ваш 512-байтовый файл занял 102 байта:

using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using ProtoBuf;

class Program
{
    static void Main()
    {
        // load your data
        Model model;
        using(var file = File.OpenRead("my.xml"))
        {
            model = (Model)new XmlSerializer(typeof(Model)).Deserialize(file);
        }
        // write as protobuf-net
        using (var file = File.Create("my.bin"))
        {
            Serializer.Serialize(file, model);
        }
    }
}

[XmlRoot("XML"), ProtoContract]
public class Model
{
    [XmlElement("Group"), ProtoMember(1)]
    public List<Group> Groups { get; set; }

}
[ProtoContract]
public class Group
{
    [XmlAttribute("Name"), ProtoMember(1)]
    public string Name { get; set; }

    [XmlElement("PIN"), ProtoMember(2)]
    public List<Pin> Pins { get; set; }
}
[ProtoContract]
public class Pin
{
    [XmlAttribute("Name"), ProtoMember(1)]
    public string Name { get; set; }

    [XmlElement("PAIR"), ProtoMember(2)]
    public List<Pair> Pairs { get; set; }
}
[ProtoContract]
public class Pair
{
    [ProtoMember(1)]
    public int Voltage { get; set; }
    [ProtoMember(2)]
    public int Current { get; set; }
}
...