2016-10-16 6 views
0

У меня есть проект C#, который сериализует список объектов в xml.Добавление рекурсивной структуры папок для сериализации 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 с использованием сериализованных объектов?

+0

Вам нужно анализировать, используя папку вместо пункта. Вы можете получить родительский элемент, но мне лично не нравится использование родительского свойства. – jdweng

ответ

0

Это должно быть классная структура.

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; } 
} 
+0

Глядя на это, я считаю, что это сделало бы папки обязательными (а не факультативными), а также всегда фиксированными на двух уровнях в глубину. – user2921789

+0

Вы можете использовать необязательный атрибут для этого –

0

После нескольких проб и ошибок мне удалось получить функциональность, которой я был.

[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>