2013-07-18 10 views
0

나는이 사용하는 C 번호와 IXmlSerializable 인터페이스에는 직렬화하려고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> 

의 형식으로 XML을 가지고있다. 3 개의 클래스가 있으며, 모두 IXmlSerializable 인터페이스를 상속받습니다. XML은 최상위 클래스에서 읽히므로 "xml"유형의 XML을 child 객체 serialiser로 전달할 때 루프됩니다. 그런 다음 "목록"일련 번호가 모든 "기능"항목을 반복합니다. 아래는 내 코드의 축소 된 버전입니다.

루핑에 대한 여러 접근법을 시도했지만 무한 루프, 잘못된 유형의 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을 구현할 아무런 이유가 없다. 직렬화 할 수있는 Dictionary 타입을 만들기 위해 함께 번들로 묶인 코드의 시작점 일 뿐이다. –

+0

나는 지금 검색 중이지만 다른 누군가가 더 빠르면 다른 사람들을 돕기 위해 앞으로는 어떤 지시어를 사용 하는가? [Serializable] 속성이 필요합니까? –

+0

아, 그 "using System;" –