2013-07-18 94 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

好的,它的“使用系统”; –