2009-08-06 6 views
13

Первый вопрос на Stackoverflow (.Net 2.0):XML Сериализация Список <T> - XML ​​Root

Так что я пытаюсь вернуть XML из списка со следующим:

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

Теперь это будет будет использоваться для нескольких объектов, которые я уже определил.

Скажите, что я хотел бы получить XML из List<Cat>

XML-бы что-то вроде:

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

Есть ли способ для меня, чтобы получить тот же корень все время при получении этих сущностей ?

Пример:

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

Также обратите внимание, что я не собираюсь десериализации XML обратно List<Cat>

+0

Что вы подразумеваете под «получить тот же корень все время»? Пожалуйста, дайте более подробную информацию ... –

ответ

30

Существует гораздо простой способ:

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

Если я правильно понимаю, вы хотите, корень документа, чтобы всегда быть такой же, независимо от тип элемента в коллекции? В этом случае вы можете использовать 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

Отлично, работал как шарм. Спасибо –

6

Лучший способ к тому же:

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

Не возражаете ли вы объяснить, почему это лучше? –

+0

Главное, что он сериализуется непосредственно в XmlDocument. Ваш код должен анализировать результаты, чтобы вернуть их в документ. В вашем коде также использовался XmlTextWriter, который в значительной степени устарел. –

+0

Понял, спасибо большое. –

2

так просто ....

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

Вы идете только на один уровень. Конечно, это просто. – James