2009-08-06 13 views
13

Première question sur Stackoverflow (.Net 2.0):sérialisation XML de la liste <T> - XML ​​Racine

Je suis en train de retourner un fichier XML d'une liste avec les éléments suivants:

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

Maintenant, cette volonté être utilisé pour plusieurs entités que j'ai déjà définies.

dire que je voudrais obtenir un fichier XML de List<Cat>

Le XML serait quelque chose comme:

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

Est-il possible pour moi d'obtenir la même racine tout le temps lors de l'obtention de ces entités ?

Exemple:

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

Notez également que je ne veux pas désérialiser le XML Retour à List<Cat>

+0

Que voulez-vous dire par "obtenir la même racine tout le temps"? S'il vous plaît donner plus de détails ... –

Répondre

30

Il y a beaucoup moyen facile:

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

Si je comprends bien, vous voulez la racine du document à toujours le même, quel que soit le type d'élément dans la collection? Dans ce cas, vous pouvez utiliser 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

Super, travaillé comme un charme. Merci –

6

Une meilleure façon de la même chose:

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

Cela vous dérange-t-il d'expliquer pourquoi c'est mieux? –

+0

Le principal est qu'il se sérialise directement dans le XmlDocument. Votre code requis analyser les résultats afin de les récupérer dans le document. Votre code a également utilisé XmlTextWriter, qui est en grande partie obsolète. –

+0

Compris, merci beaucoup. –

2

si simple ....

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

Vous descendez seulement d'un niveau. Bien sûr, c'est simple. – James