2009-08-06 23 views
13

primera pregunta sobre Stackoverflow (.Net 2.0):de lista <T> - Raíz XML

así que estoy tratando de devolver un XML de una lista con lo siguiente:

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

Ahora bien, esta voluntad ser utilizado para múltiples Entidades que ya he definido.

decir te gustaría obtener un XML de List<Cat>

El XML sería algo así como:

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

¿Hay alguna manera para que consiga la misma raíz todo el tiempo al conseguir estas entidades ?

Ejemplo:

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

También tenga en cuenta que no tengo la intención deserializar el XML de nuevo a List<Cat>

+0

¿Qué quiere decir con "obtener la misma raíz todo el tiempo"? Por favor, dar más detalles ... –

Respuesta

30

Hay una manera mucho más fácil:

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 he entendido bien, desea que la raíz del documento sea siempre la misma, cualquiera que sea el tipo de elemento en la colección? En ese caso se puede utilizar 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

Genial, funcionó como un encanto. Gracias –

6

Una mejor manera de lo mismo:

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

¿Te importa explicar por qué es mejor sin embargo? –

+0

Lo principal es que se serializa directamente en XmlDocument. Su código requiere analizar los resultados para poder volverlos a introducir en el documento. Su código también usó XmlTextWriter, que es en gran parte obsoleto. –

+0

Entendido, muchas gracias. –

2

tan 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

Solo baja un nivel. Por supuesto es simple. – James

Cuestiones relacionadas