2009-08-06 9 views
13

Erste Frage auf Stackoverflow (.NET 2.0):XML-Serialisierung von List <T> - XML ​​Wurzel

Also ich versuche, eine XML einer Liste mit folgenden zurückzukehren:

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

jetzt hier für mehrere Entitäten verwendet werden, die ich bereits definiert habe.

Sagen wir, ich möchte ein XML von List<Cat>

Die XML so etwas bekommen wäre:

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

Gibt es eine Möglichkeit für mich die gleiche Wurzel all diese Entitäten, die Zeit zu erhalten, wenn immer ?

Beispiel:

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

Beachten Sie auch, dass ich nicht die Absicht, die XML deserialisiert zurück zu List<Cat>

+0

Was meinst du mit "bekomme die gleiche Wurzel die ganze Zeit"? Bitte geben Sie weitere Details ... –

Antwort

30

Es gibt eine viel einfacher Weg:

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

Wenn ich richtig verstehe, wollen Sie die Wurzel des Dokuments immer gleich sein, was auch immer der Typ des Elements in der Sammlung? In diesem Fall können Sie XmlAttributeOverrides verwenden:

 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

Großartig, arbeitete wie ein Charme. Danke –

6

Eine bessere Möglichkeit, auf dasselbe hinaus:

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

Stört es Sie zu erklären, warum es besser ist? –

+0

Die Hauptsache ist, dass es direkt in das XmlDocument serialisiert. Ihr Code musste die Ergebnisse analysieren, um sie wieder in das Dokument zu bekommen. Ihr Code verwendete auch XmlTextWriter, der weitgehend veraltet ist. –

+0

Verstanden, vielen Dank. –

2

so einfach ....

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

Sie gehen nur eine Ebene tiefer. Natürlich ist es einfach. – James