Lorsque j'utilise un sérialiseur .NET XML standard, puis-je masquer toutes les valeurs nulles? Voici un exemple de la sortie de ma classe. Je ne veux pas sortir les entiers nullables s'ils sont mis à null.
Sortie XML actuelle:
<?xml version="1.0" encoding="utf-8"?>
<myClass>
<myNullableInt p2:nil="true" xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" />
<myOtherInt>-1</myOtherInt>
</myClass>
Ce que je veux:
<?xml version="1.0" encoding="utf-8"?>
<myClass>
<myOtherInt>-1</myOtherInt>
</myClass>
Vous pouvez créer une fonction avec le modèle ShouldSerialize{PropertyName}
qui indique à XmlSerializer s'il doit ou non sérialiser le membre.
Par exemple, si votre propriété de classe s'appelle MyNullableInt
, vous pourriez avoir
public bool ShouldSerializeMyNullableInt()
{
return MyNullableInt.HasValue;
}
Voici un échantillon complet
public class Person
{
public string Name {get;set;}
public int? Age {get;set;}
public bool ShouldSerializeAge()
{
return Age.HasValue;
}
}
Sérialisé avec le code suivant
Person thePerson = new Person(){Name="Chris"};
XmlSerializer xs = new XmlSerializer(typeof(Person));
StringWriter sw = new StringWriter();
xs.Serialize(sw, thePerson);
Résultats dans le code XML suivant - Notez qu'il n'y a pas d'âge
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Chris</Name>
</Person>
En plus de ce que Chris Taylor a écrit: si vous avez quelque chose de sérialisé en tant qu'attribut, vous pouvez avoir une propriété sur votre classe nommée {PropertyName}Specified
pour contrôler si elle doit être sérialisée. Dans du code:
public class MyClass
{
[XmlAttribute]
public int MyValue;
[XmlIgnore]
public bool MyValueSpecified;
}
Il existe une propriété appelée XmlElementAttribute.IsNullable
Si la propriété IsNullable est définie sur true, l'attribut xsi: nil est généré pour les membres de la classe qui ont été définis sur une référence null.
L'exemple suivant montre un champ avec la variable XmlElementAttribute
qui lui est appliquée et la propriété IsNullable définie sur false.
public class MyClass
{
[XmlElement(IsNullable = false)]
public string Group;
}
Vous pouvez jeter un coup d'œil à XmlElementAttribute
pour changer de nom dans la sérialisation, etc.
Vous pouvez définir des valeurs par défaut et empêcher la sérialisation des champs.
[XmlElement, DefaultValue("")]
string data;
[XmlArray, DefaultValue(null)]
List<string> data;
private static string ToXml(Person obj)
{
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add(string.Empty, string.Empty);
string retval = null;
if (obj != null)
{
StringBuilder sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() { OmitXmlDeclaration = true }))
{
new XmlSerializer(obj.GetType()).Serialize(writer, obj,namespaces);
}
retval = sb.ToString();
}
return retval;
}
Dans mon cas, les variables/éléments nullables étaient tous de type String. J'ai donc simplement effectué une vérification et leur ai attribué string.Empty en cas de valeur NULL. De cette façon, je me suis débarrassé des attributs nil et xmlns inutiles (p3: nil = "true" xmlns: p3 = "http://www.w3.org/2001/XMLSchema-instance)
// Example:
myNullableStringElement = varCarryingValue ?? string.Empty
// OR
myNullableStringElement = myNullableStringElement ?? string.Empty
Je préfère créer mon propre fichier XML sans balises générées automatiquement. En cela, je peux ignorer la création des nœuds avec des valeurs NULL:
public static string ConvertToXML<T>(T objectToConvert)
{
XmlDocument doc = new XmlDocument();
XmlNode root = doc.CreateNode(XmlNodeType.Element, objectToConvert.GetType().Name, string.Empty);
doc.AppendChild(root);
XmlNode childNode;
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
foreach (PropertyDescriptor prop in properties)
{
if (prop.GetValue(objectToConvert) != null)
{
childNode = doc.CreateNode(XmlNodeType.Element, prop.Name, string.Empty);
childNode.InnerText = prop.GetValue(objectToConvert).ToString();
root.AppendChild(childNode);
}
}
return doc.OuterXml;
}