2011-03-02 55 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