-
Автор темы
- #1
Продолжаю делиться своими наработками из различных проектов. Когда-то мне нужно было сделать LUA систему для программы с функцией сохранения настроек скриптов. Естественно, использовать файл .settings было глупо, поэтому выбор пал на JSON или XML файлы. Заказчик попросил реализовать все в XML, потому что просто когда-то слышал это слово)). Так как все настройки имели тип <Key, Value>, странно было не использовать в этих целях словари Dictionary, однако при использовании сериализации в библиотеке
Остается только допилить функционал чтения и записи XML настроек в файл. Можете использовать мой код, как пример:
В итоге очень легко можно получить хранящуюся в "памяти" луа скрипта настройку.
System.Xml
такой возможности не предоставлялось. Поэтому пришлось найти на просторах интернета класс сериализируемого словаря и немного изменять его под себя.
C#:
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue>
: Dictionary<TKey, TValue>, IXmlSerializable
{
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
reader.ReadStartElement("key");
TKey key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement("value");
TValue value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement("item");
writer.WriteStartElement("key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
writer.WriteStartElement("value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion
}
C#:
public class LSettings
{
public String XMLFileName = Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(@"\")) + "\\LUASettings.xml";
public SerializableDictionary<string, SerializableDictionary<string, object>> LuaSettings = new SerializableDictionary<string, SerializableDictionary<string, object>>();
}
public class LuaSettings
{
public LSettings settings;
public LuaSettings()
{
settings = new LSettings();
}
public void WriteXml()
{
XmlSerializer serializer = new XmlSerializer(typeof(SerializableDictionary<string, SerializableDictionary<string, object>>));
TextWriter textWriter = new StreamWriter(settings.XMLFileName, false, Encoding.GetEncoding(1251));
serializer.Serialize(textWriter, settings.LuaSettings);
textWriter.Close();
}
public void ReadXml()
{
if (File.Exists(settings.XMLFileName))
{
XmlSerializer ser = new XmlSerializer(typeof(SerializableDictionary<string, SerializableDictionary<string, object>>));
TextReader reader = new StreamReader(settings.XMLFileName, Encoding.GetEncoding(1251));
settings.LuaSettings = ser.Deserialize(reader) as SerializableDictionary<string, SerializableDictionary<string, object>>;
reader.Close();
}
else
{
File.Create(settings.XMLFileName).Close();
settings.LuaSettings = new SerializableDictionary<string, SerializableDictionary<string, object>>();
WriteXml();
}
}
}
lSettings.settings.LuaSettings["Lua"]["Setting"]
(естественно, нужно инициализировать lSettings класса LuaSettings и занести в него все прочитанные данные lSettings.ReadXml();