Can I serialize large XML files to a binary format, and still be able to use XPath?
** Brief Explanation ** In my C# WinForms program, I have 2 TreeView's (They work like a ListView so they are not nested) and 1 ListView. I populate the first TreeView with data from some XML files (name of file as TreeNode.Text property and TreeNode.Name will contain path to the XML file).
First TreeView: When user clicks on any node, the second TreeView will populate with some data from inside of the XML file.
Second TreeView: When user clicks on any node, again some data from the XML file will be shown in ListView.
ListView: When user clicks on any item, again some data from the xml file will be shown (in my case, it is coordinates of a curve that I draw on a PictureBox).
** Visualation ** A very short e开发者_JAVA技巧xample of my XML files:
<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>
So my idea is, Since my XML files are sometimes very large (More than 10MB) it is really slow to deal with them. I wonder if there is a way to convert them in Binary and work with similar commands like 'XPATH' and 'XmlDocument' with this binary file?
Serializing it as binary shouldn't be a problem - in fact, it would be an ideal scenario for protobuf-net, since this is a tree-serializer (like XmlSerializer
), and can even work with the XmlElementAttribute
s if you really want (so you don't need any more decoration).
However, most serializations will not allow you to filter (etc) on the file while it is just a file - you would need to rehydrate the object model into a regular object model, and work with that. Fortunately, with a fast binary serializer like that, it should be faster to load anyway (and much smaller than 10MB).
However, another viable option is to use an embedded database, and write the data as records in an indexed table structure that supports the queries you need.
For info, a quick test with your sample data showed it taking your 512 byte file to 102 bytes:
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; }
}
精彩评论