このxml構造を逆シリアル化しようとしています。
<?xml version="1.0"?>
<DietPlan>
<Health>
<Fruit>Test</Fruit>
<Fruit>Test</Fruit>
<Veggie>Test</Veggie>
<Veggie>Test</Veggie>
</Health>
</DietPlan>
そして私は試しました:
[Serializable]
[XmlRoot(ElementName = "DietPlan")]
public class TestSerialization
{
[XmlArray("Health")]
[XmlArrayItem("Fruit")]
public string[] Fruits { get; set; }
[XmlArray("Health")]
[XmlArrayItem("Veggie")]
public string[] Veggie { get; set; }
}
ただし、これにより、「XML要素は現在のスコープにすでに存在します。XML属性を使用して、要素に別のXML名または名前空間を指定してください」という例外がスローされます。事前に感謝します。
XMLを逆シリアル化できるようにするには、共通の型が必要です。これを使用して、以下に示すように、要素の名前に応じてインスタンス化する型を[XmlElement]
名前空間で定義できます。
public class StackOverflow_15907357
{
const string XML = @"<?xml version=""1.0""?>
<DietPlan>
<Health>
<Fruit>Test</Fruit>
<Fruit>Test</Fruit>
<Veggie>Test</Veggie>
<Veggie>Test</Veggie>
</Health>
</DietPlan>";
[XmlRoot(ElementName = "DietPlan")]
public class TestSerialization
{
[XmlArray("Health")]
[XmlArrayItem("Fruit", Type = typeof(Fruit))]
[XmlArrayItem("Veggie", Type = typeof(Veggie))]
public Food[] Foods { get; set; }
}
[XmlInclude(typeof(Fruit))]
[XmlInclude(typeof(Veggie))]
public class Food
{
[XmlText]
public string Text { get; set; }
}
public class Fruit : Food { }
public class Veggie : Food { }
public static void Test()
{
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
XmlSerializer xs = new XmlSerializer(typeof(TestSerialization));
TestSerialization obj = (TestSerialization)xs.Deserialize(ms);
foreach (var food in obj.Foods)
{
Console.WriteLine("{0}: {1}", food.GetType().Name, food.Text);
}
}
}