次の形式の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 インターフェイスを使用してこれをシリアル化しようとしています。私は 3 つのクラスを持っています。これらはすべてインターフェイス IXmlSerializable を継承しています。私の意図は、XML が最上位のクラスによって読み込まれ、型「リスト」の xml を子オブジェクト シリアライザーに渡すことをループすることです。次に、「リスト」シリアライズは、すべての「機能」エントリをループします。以下は私のコードの縮小版です。
私はループに対していくつかのアプローチを試みましたが、常に無限ループ、間違ったタイプの 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
}