2013-07-18 93 views
0

我對XML在XML序列化

<?xml version="1.0" ?> 
<manifest attr="TEXT" attr="TEXT" attr="TEXT"> 
<list name="TRIM"> 
    <feature id="TEXT"/> 
    <feature id="TEXT"/> 
    <feature id="TEXT"/> 
    <feature id="TEXT"/> 
    <feature id="TEXT"/> 
</list> 
<list attr="TEXT"> 
    <feature id="TEXT"/> 
    <feature id="TEXT"/> 
</list> 
<list attr="TEXT"/> 
<list attr="TEXT"> 
    <feature id="TEXT" attr="TEXT"/> 
    <feature id="TEXT" attr="TEXT"/> 
</list> 
</manifest> 

我想這個連載使用C#和IXmlSerializable接口格式。我有三個類,它們都繼承了IXmlSerializable接口,我的意圖是XML將由最上層的類讀入,並且它將通過將「list」類型的xml傳遞給子對象序列化程序來循環。然後「list」序列化依次循環所有「功能」條目。以下是我的代碼的減少版本。

我已經嘗試了幾種循環方法,但總是以無限循環結束,因嘗試將錯誤類型的xml錯誤位串行化而導致錯誤,或者在跳過整個列表後到達結尾。

我是新來的Xml序列,而這種做法是幼稚的,我願意接受任何建議。

此XML很可能會在將來改變(多個屬性,元素類型等)等等必須維護,我不能保證空元素將不存在任一。

using UnityEngine; 
using System.Collections; 
using System.Xml.Serialization; 

[XmlRoot("partManifest")] 
public class ModelManifest : IEnumerator, IEnumerable, IXmlSerializable { 

    [XmlRoot("feature")] 
    public class Feature : IXmlSerializable 
    { 
     string m_id; 
     string m_description; 

     #region IXmlSerializable implementation 
     System.Xml.Schema.XmlSchema System.Xml.Serialization.IXmlSerializable.GetSchema()  
     { 
      throw new System.NotImplementedException(); 
     } 

     void System.Xml.Serialization.IXmlSerializable.ReadXml (System.Xml.XmlReader reader) 
     {  
     m_id = reader.GetAttribute("id"); 
     } 

     void System.Xml.Serialization.IXmlSerializable.WriteXml (System.Xml.XmlWriter writer) 
     { 
     throw new System.NotImplementedException(); 
     } 
     #endregion 
    } 

    [XmlRoot("feature-list")] 
    public class FeatureList : IXmlSerializable 
    { 
     string m_name; 

     System.Collections.Generic.List<Feature> m_features = new System.Collections.Generic.List<Feature>(); 

     #region IXmlSerializable implementation 
     public System.Xml.Schema.XmlSchema GetSchema() 
     { 
      throw new System.NotImplementedException(); 
     } 

     public void ReadXml (System.Xml.XmlReader reader) 
     {    
      XmlSerializer valueSerializer = new XmlSerializer(typeof(Feature)); 

      // Will return if no features present 
      if(reader.IsEmptyElement) 
       return; 

      reader.ReadStartElement("feature-list"); 
      while(true) 
      { 
       m_features.Add ((Feature)valueSerializer.Deserialize(reader)); 
       i++; 
       bool l_isAnotherSibling = reader.ReadToNextSibling("feature"); 

       if(!l_isAnotherSibling) 
        break; 
      } 
      Debug.Log (i.ToString() + " Features"); 
     } 

     public void WriteXml (System.Xml.XmlWriter writer) 
     { 
      throw new System.NotImplementedException(); 
     } 
     #endregion 
    } 

    System.Collections.Generic.List<FeatureList> m_featureLists = new System.Collections.Generic.List<FeatureList>(); 

    #region IXmlSerializable implementation 
    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     throw new System.NotImplementedException(); 
    } 

    public void ReadXml (System.Xml.XmlReader reader) 
    {  
     XmlSerializer valueSerializer = new XmlSerializer(typeof(FeatureList)); 

     if(reader.IsEmptyElement) 
      return; 

     reader.ReadStartElement("partManifest"); 

     while (true) 
     {    
      m_featureLists.Add ((FeatureList)valueSerializer.Deserialize(reader)); 

      //bool l_isAnotherSibling = reader.ReadToNextSibling("feature-list"); 

      //if(!l_isAnotherSibling) 
      // break; 
      if(reader.NodeType == System.Xml.XmlNodeType.EndElement) 
       break; 

      if(Input.GetKeyUp(KeyCode.A)) 
       break; 
     } 

     reader.ReadEndElement(); 
    } 

    public void WriteXml (System.Xml.XmlWriter writer) 
    { 
     throw new System.NotImplementedException(); 
    } 
    #endregion 
} 
+0

我聽說過使用C#性能直接序列化的對象,這會不會適用於要素類的情況? –

+0

您是否試圖將其序列化爲已定義的C#對象? – AntLaC

+1

在visual studio中,您可以右鍵單擊XML文件並說'生成模式'。它會爲你創建一個XSD。然後你可以使用像XSD2Code這樣的工具來生成一個C#類,它將會像這樣序列化。 – K0D4

回答

2

除非你有一個很好的理由需要實現IXmlSerializable的,我只想用XmlSerializer的和適當的類屬性。

基於給定的XML例子,這應該這樣做。請注意,我必須重命名清單中的兩個attr屬性,因爲具有多個具有相同名稱的屬性是無效的。

using System; 
using System.Collections.Generic; 
using System.Xml; 
using System.Xml.Schema; 
using System.Xml.Serialization; 

[Serializable] 
[XmlRoot("manifest")] 
public class Manifest 
{ 
    [XmlElement("list")] 
    public List<FeatureList> FeatureLists { get; set; } 

    [XmlAttribute("attr")] 
    public string Attr { get; set; } 

    [XmlAttribute("attr2")] 
    public string Attr2 { get; set; } 

    [XmlAttribute("attr3")] 
    public string Attr3 { get; set; } 
} 

[Serializable] 
public class FeatureList 
{ 
    [XmlElement("feature")] 
    public List<Feature> Features { get; set; } 

    [XmlAttribute("name")] 
    public string Name { get; set; } 

    [XmlAttribute("attr")] 
    public string Attr { get; set; } 
} 

[Serializable] 
public class Feature 
{ 
    [XmlAttribute("id")] 
    public string Id { get; set; } 

    [XmlAttribute("attr")] 
    public string Attr { get; set; } 
} 

使用這樣的代碼:

var stream = ... // open the XML 
var serializer = new XmlSerializer(typeof (Manifest)); 
var manifest = (Manifest) serializer.Deserialize(stream); 
+0

輝煌,謝謝,我現在試試這個。我沒有好的理由實施IXmlSerializable的,它只是從一些代碼,我捆綁在一起,使一個序列化的字典式 –

+0

我現在正在尋找一個起點,但如果別人更快,用什麼指令來幫助別人的未來,我需要[Serializable]屬性嗎? –

+0

好的,它的「使用系統」; –