J'ai la classe suivante:
[Serializable]
public class SomeModel
{
[XmlElement("SomeStringElementName")]
public string SomeString { get; set; }
[XmlElement("SomeInfoElementName")]
public int SomeInfo { get; set; }
}
Ce qui (lorsqu'il est rempli avec des données de test) et sérialisé à l'aide de XmlSerializer.Serialize () résulte en XML suivant:
<SomeModel>
<SomeStringElementName>testData</SomeStringElementName>
<SomeInfoElementName>5</SomeInfoElementName>
</SomeModel>
Ce dont j'ai besoin, c'est:
<SomeModel>
<SomeStringElementName Value="testData" />
<SomeInfoElementName Value="5" />
</SomeModel>
Est-il possible de spécifier cela en tant qu'attributs sans écrire mon propre code de sérialisation personnalisé?
Vous aurez besoin de classes de wrapper:
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; }
}
ou une approche plus générique si vous préférez:
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; }
}
Et alors:
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);
}
}
produira:
<?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>
En quelque sorte, utilisez XmlAttribute
au lieu de XmlElement
, mais cela ne ressemblera pas à ce que vous voulez. Cela ressemblera à ceci:
<SomeModel SomeStringElementName="testData">
</SomeModel>
La seule façon pour moi d’atteindre ce que vous voulez (nativement) serait d’avoir des propriétés pointant sur des objets nommés SomeStringElementName et SomeInfoElementName où la classe contenait un seul getter nommé "valeur". Vous pouvez aller plus loin et utiliser DataContractSerializer afin que les classes de wrapper puissent être privées. XmlSerializer ne lira pas les propriétés privées.
// 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); }
}
}