2011-03-02 4 views
1

J'ai la structure de classe suivante que je veux sérialisation:sérialisation XML personnalisé avec l'héritage

[XmlRoot("SomeClass")] 
public class SomeClass 
{ 
    private BaseClass[] _itemArray; 
    public BaseClass[] ItemArray 
    { 
     get { return _itemArray; } 
     set { _itemArray = value; } 
    } 

    public PPSPStatReportMessage() 
     : base() 
    { 
    } 
} 

public class SomeOtherClass 
{ 
    private int _property5; 
    [XmlAttribute("Property5")] 
    public int Property5 
    { 
     get { return _property5; } 
     set { _property5 = value; } 
    } 

    private string _property6; 
    [XmlText()] 
    public string Property6 
    { 
     get { return _property6; } 
     set { _property6 = value; } 
    } 

    public SomeOtherClass() 
    { 
    } 
} 

[XmlInclude(typeof(DerivedClass1))] 
[XmlInclude(typeof(DerivedClass2))] 
[XmlRoot("BaseClass")] 
[XmlType("")] 
public class BaseClass 
{ 
    private string _property1; 
    [XmlAttribute("Property1")] 
    public string Property1 
    { 
     get { return _property1; } 
     set { _property1 = value; } 
    } 

    public SomeClass(string PropertyVal) 
    { 
     _property1 = PropertyVal; 
    } 
} 

[XmlRoot("BaseClass")] 
[XmlTypeAttribute(Namespace = "")] 
public class DerivedClass1 : BaseClass 
{ 
    private string _property2; 
    [XmlAttribute("Property2")] 
    public string Property2 
    { 
     get { return _property2; } 
     set { _property2 = value; } 
    } 


    private SomeOtherClass _property3; 
    [XmlElement("SomeOtherClass")] 
    public SomeOtherClass Property3 
    { 
     get { return _property3; } 
     set { _property3 = value; } 
    } 

    public DerivedClass() 
     : base("PropertyVal1") 
    { 
    } 
} 

[XmlRoot("BaseClass", Namespace = "")] 
[XmlType("")] 
public class DerivedClass2 : BaseClass 
{ 
    private Int64 _property4; 
    [XmlAttribute("Property4")] 
    public Int64 Property4 
    { 
     get { return _property4; } 
     set { _property4 = value; } 
    } 

    public DerivedClass2() 
     : base("PropertyVal2") 
    { 
    } 
} 

C'est la méthode que j'utilise pour sérialiser SomeClass:

public static string SerializeXML(object Value, System.Type ObjectType) 
    { 
     XmlSerializer serializer = new XmlSerializer(ObjectType); 
     XmlSerializerNamespaces namespaceSerializer = new XmlSerializerNamespaces(); 
     namespaceSerializer.Add("", ""); 
     StringWriter ms = new StringWriter(); 
     serializer.Serialize(ms, Value, namespaceSerializer); 
     return ms.ToString(); 
    } 

Cette méthode génère un XML structure qui ressemble à ce qui suit:

<?xml version="1.0" encoding="utf-16"?> 
<SomeClass> 
    <ItemArray> 
    <BaseClass d3p1:type="DerivedClass1" Property1="PropertyVal1" Property2="123" xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance"> 
     <SomeOtherClass Property5="0" >STRING DATA</SomeOtherClass> 
    </BaseClass> 
    <BaseClass d3p1:type="DerivedClass2" Property="PropertyVal2" Property4="456" xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance" /> 
    </ItemArray> 
</SomeClass> 

Cependant, je dois omettre le d3p1: type et xm LNS: attributs de d3p1 et générer une structure XML qui ressemble à ceci:

<?xml version="1.0" encoding="utf-16"?> 
<SomeClass> 
    <ItemArray> 
    <BaseClass Property1="PropertyVal1" Property2="123"> 
     <SomeOtherClass Property5="0" >STRING DATA</SomeOtherClass> 
    </BaseClass> 
    <BaseClass Property="PropertyVal2" Property4="456" /> 
    </ItemArray> 
</SomeClass> 

Comme vous pouvez le voir dans le code, j'ai essayé d'utiliser XmlType et XmlTypeAttribute, mais sans succès.

Un conseil sur comment puis-je générer la structure XML comme décrit ci-dessus (sans les attributs d3p1: type et xmlns: d3p1)?

+0

XmlSerializer.Deserialize a besoin de cela pour fonctionner correctement. Ne désérialisez-vous jamais? –

+0

Je suis sérialisation, mais je vérifie la propriété "Propriété" pour savoir quel type d'objet sera utilisé pour désérialiser. – IraqiGeek

+0

Ment désérialisant ... – IraqiGeek

Répondre

0
XmlWriterSettings settings = new XmlWriterSettings(); 
settings.OmitXmlDeclaration = true; 
settings.Indent = true; 

using (XmlWriter writer = XmlWriter.Create(file, settings)) 
{ 
    XmlSerializer serializer = new XmlSerializer(source.GetType()); 

    XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); 
    namespaces.Add(string.Empty, string.Empty); 
    // ... 
} 
+0

Salut, Merci pour la réponse. J'ai essayé d'utiliser un XmlWriter, mais il donne les mêmes résultats (ie: avoir encore xmlns et taper dans le xml généré) – IraqiGeek

3

Vous ne pouvez pas accomplir ce que vous voulez directement.

Si le type en cours de sérialisation n'est pas le type exact contenu, .NET doit effectuer le suivi de ce type pour permettre une désérialisation correcte.

Pour accomplir ce que vous voulez, utilisez RegEx.Replace() ou un autre post-traitement pour remplacer les espaces de noms. (Par exemple, la sérialisation d'un objet qui est réellement une chaîne provoquera ce problème).

2

Avez-vous besoin que les éléments de la sous-classe soient appelés "BaseClass" - ou le nom de la classe dérivée le ferait-il? Je suis en train de sérialiser des structures de sous-classes similaires, et je voulais aussi me débarrasser des balises "d3p1: type" et "xmlns: d3p1" - au lieu de remplacer les balises "BaseClass" par des balises de classe dérivées. Il est donc possible de générer xml pour votre exemple:

<ItemArray> 
    <DerivedClass1 Property1="PropertyVal1" Property2="123"> 
     .... 
    </DerivedClass1> 

Vous utilisez un attribut XmlInclude sur votre BaseClass pour laisser le serliazer savoir qui tirait les classes à attendre. Au lieu de cela, vous pouvez dire au sujet des sous-types sérialiseur attendus sur chaque élément:

public class SomeClass 
{ 
    private BaseClass[] _itemArray; 

    [XmlElement(typeof(DerivedClass1))] 
    [XmlElement(typeof(DerivedClass2))] 
    public BaseClass[] ItemArray 
    { 
     get { return _itemArray; } 
     set { _itemArray = value; } 
} 

L'élimination du « type » attributs. La désérialisation fonctionnera également très bien.

+0

Tryptamine42, ça marche parfaitement. Merci! – bigmac