我可以将大型XML文件序列化为二进制格式,并且仍然可以使用XPath吗?

时间:2011-05-05 20:03:01

标签: c# serialization xml-serialization

**简要说明** 在我的C#WinForms程序中,我有2个TreeView(它们像ListView一样工作,因此它们不是嵌套的)和1个ListView。我使用来自某些XML文件的数据填充第一个TreeView(文件名称为TreeNode.Text属性,TreeNode.Name将包含XML文件的路径)。

第一个TreeView: 当用户单击任何节点时,第二个TreeView将填充XML文件内部的一些数据。

第二个TreeView: 当用户点击任何节点时,XML文件中的一些数据将再次显示在ListView中。

的ListView: 当用户点击任何项目时,将再次显示xml文件中的一些数据(在我的例子中,它是我在PictureBox上绘制的曲线的坐标)。

** Visualation ** 我的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文件有时非常大(超过10MB),因此处理它们的速度非常慢。我想知道是否有办法在Binary中转换它们并使用类似的命令,如'XPATH'和'XmlDocument'与这个二进制文件一起工作?

1 个答案:

答案 0 :(得分:2)

将其序列化为二进制应该不是问题 - 事实上,它将是protobuf-net的理想场景,因为这是一个树序列化器(如XmlSerializer) ,如果你真的想要,甚至可以使用XmlElementAttribute s(所以你不需要任何装饰)。

但是,大多数序列化都不允许您对文件进行过滤(等),因为它只是一个文件 - 您需要将对象模型重新水化为常规对象模型,并使用它。幸运的是,使用这样的快速二进制序列化器,无论如何加载速度应该更快(并且远小于10MB)。

但是,另一个可行的选择是使用嵌入式数据库,并将数据作为记录写入支持所需查询的索引表结构中。

有关信息,使用示例数据进行快速测试表明它将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; }
}