2010-04-10 2 views
4

У меня есть список, который заполняется объектами различных конкретных типов, подкласс BaseTypeКак сериализовать коллекцию базового типа и увидеть конкретные типы в удобном для чтения XML

Я использую WCF DataContractSerializer

<Children> 
    <BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks" 
       i:type="d3p1:ConcreteTypeA"></BaseType> 
    <BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks" 
       i:type="d3p1:ConcreteTypeB"></BaseType> 
</Children> 

есть ли способ, чтобы получить это, чтобы генерировать

<Children> 
    <ConcreteTypeA/> 
    <ConcreteTypeB/> 
</Children> 

?

Настоящая цель - дать пользователям возможность генерировать XML-данные для загрузки в память, а пользователи уровня квалификации, требующие оригинального XML, не будут успешными.

+0

вы должны дать пример кода, что вы хотите .. – Nix

+0

он сделал, это не было отмечено должным образом , Я исправил его для него. – Josh

ответ

7

DataContractSerializer не предназначен для управления выходом. Он предназначен для быстрого, неявного и простого атрибута класса.

Что вы хотите, это XmlSerializer. Это дает вам больший контроль над выходом XML.

Обратите внимание, что в моем примере ниже я указал много вещей, которые могли быть выведены из имен свойств, но только для того, чтобы дать вам понять, что вы можете переопределить их в атрибутах. На самом деле я думаю, что весь этот класс будет сериализоваться просто отлично, если бы все атрибуты были удалены, а некоторые KnownTypeAttributes были применены, но я не тестировал его. Я не знаю, даст ли это вам точный XML, который вы описали (он создаст корневой элемент выше Children), но, надеюсь, это приведет вас в правильном направлении.

Attributes That Control XML Serialization

[XmlRoot(Namespace="")] 
public class MyClass { 

    [XmlArray("Children")] 
    [XmlArrayItem("ConcreteTypeA", typeof(ConcreteTypeA))] 
    [XmlArrayItem("ConcreteTypeB", typeof(ConcreteTypeB))] 
    public BaseType[] Children { 
     get; 
     set; 
    } 

} 

public class BaseType { 
} 

public class ConcreteTypeA : BaseType { 
} 

public class ConcreteTypeB : BaseType { 
} 

EDIT: Я просто проверял и производит что-то очень близкое к тому, что вы искали.

void Main() 
{ 

    var mc = new MyClass(); 
    mc.Children = new BaseType[] { 
     new ConcreteTypeA(), 
     new ConcreteTypeB(), 
     new ConcreteTypeA(), 
     new ConcreteTypeB() 
    }; 

    var serializer = new XmlSerializer(typeof(MyClass)); 

    using (var str = new StringWriter()) { 
     serializer.Serialize(str, mc); 
     str.ToString().Dump(); 
    } 

} 

... производит ... (бесполезное XMLNS удаляется из верхних)

<MyClass> 
    <Children> 
    <ConcreteTypeA /> 
    <ConcreteTypeB /> 
    <ConcreteTypeA /> 
    <ConcreteTypeB /> 
    </Children> 
</MyClass> 
+0

Могу ли я добавлять известные типы во время выполнения, а не через атрибуцию? Типы могут быть добавлены пользователем через модель плагина. –

+0

Да, есть перегрузка конструктора XmlSerializer, который позволяет передавать дополнительные типы для рассмотрения в массиве типов. http://msdn.microsoft.com/en-us/library/e5aakyae(v=VS.90).aspx – Josh

Смежные вопросы