2011-03-02 54 views
1

自定义XML序列化我有我想要序列下面的类结构:与继承

[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") 
    { 
    } 
} 

这是我使用的序列化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(); 
    } 

这种方法生成的XML结构看起来像下面这样:

<?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> 

但是,我需要省略d3p1:type和xm LNS:d3p1属性,并生成一个XML结构是这样的:

<?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> 

正如你可以在代码中看到,我试图用XmlType将和XmlTypeAttribute,但没有成功。

有关如何生成上述XML结构(不包括d3p1:type和xmlns:d3p1属性)的任何建议?

+0

XmlSerializer.Deserialize需要它才能正常工作。你从来没有反序列化? – 2011-03-02 16:57:25

+0

我在序列化,但我检查“Property”属性以知道将使用哪个对象类型进行反序列化。 – IraqiGeek 2011-03-02 18:27:28

+0

Meant反序列化... – IraqiGeek 2011-03-02 18:27:59

回答

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

嗨,谢谢你的回复。我尝试使用XmlWriter,但它给出了相同的结果(即:仍然有生成的xml中的xmlns和类型) – IraqiGeek 2011-03-02 17:25:08

3

你不能直接完成你想要的。

如果被序列化的类型不是包含的确切类型,.NET必须跟踪类型的真正用途是否允许正确的反序列化。

要完成你想要的 - 使用RegEx.Replace()或其他后处理来替换名称空间。

(例如序列化对象,这真是一个字符串将导致此问题)。

2

您是否需要将子类元素称为“BaseClass” - 或者派生类的名称是否会执行?

我序列化类似的子类结构,也希望摆脱“d3p1:type”和“xmlns:d3p1”标签 - 而不是用派生类标签替换“BaseClass”标签。因此,有可能生成XML为你的例子:

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

您使用您的BaseClass的XmlInclude属性,让serliazer知道哪个派生类的期望。相反,您可以告诉序列化程序关于每个元素上预期的子类型:

public class SomeClass 
{ 
    private BaseClass[] _itemArray; 

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

消除“类型”属性。反串行化也可以正常工作。

+0

tryptamine42,完美的作品。谢谢! – bigmac 2014-08-15 17:20:35