#c# #xml #xml-serialization
#c# #xml #xml-сериализация
Вопрос:
У меня есть проект на c #, который сериализует список объектов в xml.
[Serializable]
[XmlRoot]
public class collection {
private List<item> _items = new List<item>();
[XmlElement("item")]
public List<item> items {
get { return _items; }
}
}
[Serializable]
public class item {
}
затем вывод xml
<collection>
<item/>
<item/>
<item/>
</collection>
я хотел бы добавить опцию папок и вложенных папок, чтобы элементы можно было группировать вместе, сохраняя при этом возможность перехода в корневой узел.
<collection>
<item/>
<item/>
<folder>
<item/>
<item/>
</folder>
<item/>
<item/>
<folder>
<item/>
<item/>
<folder>
<item/>
<item/>
</folder>
</folder>
<item/>
</collection>
Может кто-нибудь посоветовать чистый способ сделать это, продолжая генерировать вывод xml с использованием сериализованных объектов?
Комментарии:
1. Вам нужно выполнить синтаксический анализ, используя folder вместо item . Вы могли бы получить родительский элемент item, но лично мне не нравится использовать родительское свойство.
Ответ №1:
Это должна быть структура классов.
public class Folder2
{
}
public class Folder
{
public Folder2 folder { get; set; }
}
public class Collection
{
public List<Folder> folder { get; set; }
}
public class RootObject
{
public Collection collection { get; set; }
}
Комментарии:
1. Глядя на это, я считаю, что это сделало бы папки обязательными (вместо необязательных), а также всегда фиксированными на двух уровнях.
2. Для этого вы можете использовать необязательный атрибут
Ответ №2:
После небольшого количества проб и ошибок мне удалось получить функциональность, которую я искал.
[Serializable]
[XmlRoot]
public class collection {
private List<treeEntry> _entries = new List<treeEntry>();
[XmlElement("item", typeof(item))]
[XmlElement("folder", typeof(folder))]
public List<treeEntry> entries {
get { return _entries; }
}
}
public abstract class treeEntry { }
[Serializable]
public class folder : treeEntry {
private List<treeEntry> _entries = new List<treeEntry>();
public folder() { }
[XmlAttribute]
public string name { get; set; }
[XmlElement("item", typeof(item))]
[XmlElement("folder", typeof(folder))]
public List<treeEntry> entries {
get { return _entries; }
}
}
[Serializable]
public class item : treeEntry { }
public class mytest {
public static void main() {
collection col = new collection();
col.entries.Add(new item());
col.entries.Add(new item());
var folder1 = new folder() { name = "someFolder" };
folder1.entries.Add(new item());
var folder2 = new folder() { name = "anotherFolder" };
folder1.entries.Add(folder2);
folder1.entries.Add(new item());
folder2.entries.Add(new item());
col.entries.Add(folder1);
col.entries.Add(new folder());
col.entries.Add(new item());
XmlSerializer sers = new XmlSerializer(typeof(collection));
//serialise
using (StreamWriter sw = new StreamWriter("testoutput.xml", false, Encoding.UTF8)) {
XmlWriter xw = new XmlTextWriter(sw);
sers.Serialize(xw, col);
}
//deserialise
FileStream fs = new FileStream("testoutput.xml", FileMode.Open);
XmlReader reader = XmlReader.Create(fs);
collection newcol = (collection)sers.Deserialize(reader);
//output to console
sers.Serialize(Console.Out, newcol);
}
}
что дало желаемый результат
<collection>
<item />
<item />
<folder name="someFolder">
<item />
<folder name="anotherFolder">
<item />
</folder>
<item />
</folder>
<folder />
<item />
</collection>