次のクラスがあります。
[Serializable]
public class SomeModel
{
[XmlElement("SomeStringElementName")]
public string SomeString { get; set; }
[XmlElement("SomeInfoElementName")]
public int SomeInfo { get; set; }
}
XmlSerializer.Serialize()を使用して(一部のテストデータを入力した場合)シリアル化すると、次のXMLが生成されます。
<SomeModel>
<SomeStringElementName>testData</SomeStringElementName>
<SomeInfoElementName>5</SomeInfoElementName>
</SomeModel>
私が持っている必要があるのは:
<SomeModel>
<SomeStringElementName Value="testData" />
<SomeInfoElementName Value="5" />
</SomeModel>
独自のカスタムシリアル化コードを記述せずに、これを属性として指定する方法はありますか?
ラッパークラスが必要になります。
public class SomeIntInfo
{
[XmlAttribute]
public int Value { get; set; }
}
public class SomeStringInfo
{
[XmlAttribute]
public string Value { get; set; }
}
public class SomeModel
{
[XmlElement("SomeStringElementName")]
public SomeStringInfo SomeString { get; set; }
[XmlElement("SomeInfoElementName")]
public SomeIntInfo SomeInfo { get; set; }
}
または、必要に応じてより一般的なアプローチ:
public class SomeInfo<T>
{
[XmlAttribute]
public T Value { get; set; }
}
public class SomeModel
{
[XmlElement("SomeStringElementName")]
public SomeInfo<string> SomeString { get; set; }
[XmlElement("SomeInfoElementName")]
public SomeInfo<int> SomeInfo { get; set; }
}
その後:
class Program
{
static void Main()
{
var model = new SomeModel
{
SomeString = new SomeInfo<string> { Value = "testData" },
SomeInfo = new SomeInfo<int> { Value = 5 }
};
var serializer = new XmlSerializer(model.GetType());
serializer.Serialize(Console.Out, model);
}
}
生成されます:
<?xml version="1.0" encoding="ibm850"?>
<SomeModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SomeStringElementName Value="testData" />
<SomeInfoElementName Value="5" />
</SomeModel>
種類として、XmlAttribute
の代わりにXmlElement
を使用しますが、それはあなたが望むもののようには見えません。次のようになります。
<SomeModel SomeStringElementName="testData">
</SomeModel>
あなたが望むものを(自然に)達成するために私が考えることができる唯一の方法は、クラスが「value」という名前の単一のgetterを含むSomeStringElementNameとSomeInfoElementNameという名前のオブジェクトを指すプロパティを持つことです。これをさらに一歩進め、DataContractSerializerを使用して、ラッパークラスをプライベートにすることができます。 XmlSerializerはプライベートプロパティを読み取りません。
// TODO: make the class generic so that an int or string can be used.
[Serializable]
public class SerializationClass
{
public SerializationClass(string value)
{
this.Value = value;
}
[XmlAttribute("value")]
public string Value { get; }
}
[Serializable]
public class SomeModel
{
[XmlIgnore]
public string SomeString { get; set; }
[XmlIgnore]
public int SomeInfo { get; set; }
[XmlElement]
public SerializationClass SomeStringElementName
{
get { return new SerializationClass(this.SomeString); }
}
}