У меня есть 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>
Я пытаюсь сериализовать это с помощью С# и интерфейса IXmlSerializable. У меня есть три класса, все из которых наследуют интерфейс 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
}