2009-08-06 16 views
13

pierwsze pytanie na StackOverflow (.NET 2.0):serializacji XML z listy <T> - XML ​​głównej

Więc staram się powrócić XML z listy z poniższym:

public XmlDocument GetEntityXml() 
    {   
     StringWriter stringWriter = new StringWriter(); 
     XmlDocument xmlDoc = new XmlDocument();    

     XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter); 

     XmlSerializer serializer = new XmlSerializer(typeof(List<T>)); 

     List<T> parameters = GetAll(); 

     serializer.Serialize(xmlWriter, parameters); 

     string xmlResult = stringWriter.ToString(); 

     xmlDoc.LoadXml(xmlResult); 

     return xmlDoc; 
    } 

Teraz będzie to być użyte dla wielu Podmiotów, które już zdefiniowałem.

Say chciałbym uzyskać XML z List<Cat>

XML byłoby coś takiego:

<ArrayOfCat> 
    <Cat> 
    <Name>Tom</Name> 
    <Age>2</Age> 
    </Cat> 
    <Cat> 
    <Name>Bob</Name> 
    <Age>3</Age> 
    </Cat> 
</ArrayOfCat> 

Czy istnieje sposób dla mnie, aby uzyskać ten sam rdzeń cały czas podczas pobierania tych podmiotów ?

Przykład:

<Entity> 
    <Cat> 
    <Name>Tom</Name> 
    <Age>2</Age> 
    </Cat> 
    <Cat> 
    <Name>Bob</Name> 
    <Age>3</Age> 
    </Cat> 
</Entity> 

Należy również pamiętać, że nie zamierzają deserializowania XML z powrotem do List<Cat>

+0

Co masz na myśli, mówiąc: "zdobywaj cały ten sam Root"? Podaj więcej szczegółów ... –

Odpowiedz

30

Jest znacznie łatwy sposób:

public XmlDocument GetEntityXml<T>() 
{ 
    XmlDocument xmlDoc = new XmlDocument(); 
    XPathNavigator nav = xmlDoc.CreateNavigator(); 
    using (XmlWriter writer = nav.AppendChild()) 
    { 
     XmlSerializer ser = new XmlSerializer(typeof(List<T>), new XmlRootAttribute("TheRootElementName")); 
     ser.Serialize(writer, parameters); 
    } 
    return xmlDoc; 
} 
8

Jeśli dobrze rozumiem, chcesz korzeniem dokumentu, aby być zawsze taka sama, niezależnie od typ elementu w kolekcji? W tym przypadku można użyć XmlAttributeOverrides:

 XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 
     XmlAttributes attr = new XmlAttributes(); 
     attr.XmlRoot = new XmlRootAttribute("TheRootElementName"); 
     overrides.Add(typeof(List<T>), attr); 
     XmlSerializer serializer = new XmlSerializer(typeof(List<T>), overrides); 
     List<T> parameters = GetAll(); 
     serializer.Serialize(xmlWriter, parameters); 
+0

Świetnie, zadziałało jak czar. Dzięki –

6

Lepszym sposobem na to samo:

public XmlDocument GetEntityXml<T>() 
{ 
    XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 
    XmlAttributes attr = new XmlAttributes(); 
    attr.XmlRoot = new XmlRootAttribute("TheRootElementName"); 
    overrides.Add(typeof(List<T>), attr); 

    XmlDocument xmlDoc = new XmlDocument(); 
    XPathNavigator nav = xmlDoc.CreateNavigator(); 
    using (XmlWriter writer = nav.AppendChild()) 
    { 
     XmlSerializer ser = new XmlSerializer(typeof(List<T>), overrides); 
     List<T> parameters = GetAll<T>(); 
     ser.Serialize(writer, parameters); 
    } 
    return xmlDoc; 
} 
+0

Czy wyjaśniasz, dlaczego jest lepiej? –

+0

Najważniejsze, że serializuje się bezpośrednio do XmlDocument. Twój kod wymagał analizy wyników, aby móc je odzyskać. Twój kod również użył XmlTextWriter, który jest w dużej mierze przestarzały. –

+0

Zrozumiano, wielkie dzięki. –

2

takie proste ....

public static XElement ToXML<T>(this IList<T> lstToConvert, Func<T, bool> filter, string rootName) 
{ 
    var lstConvert = (filter == null) ? lstToConvert : lstToConvert.Where(filter); 
    return new XElement(rootName, 
     (from node in lstConvert 
     select new XElement(typeof(T).ToString(), 
     from subnode in node.GetType().GetProperties() 
     select new XElement(subnode.Name, subnode.GetValue(node, null))))); 

} 
+0

Schodzisz tylko o jeden poziom. Oczywiście, że to proste. – James

Powiązane problemy