c# xmlelement Sérialisation Xml-Masquer les valeurs NULL




xml element with attribute c# (6)

Lorsque vous utilisez un Serializer XNET standard, est-il possible de cacher toutes les valeurs nulles? Le ci-dessous est un exemple de la sortie de ma classe. Je ne veux pas afficher les entiers nullables s'ils sont définis sur 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 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;

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 classe qui ont été définis sur une référence null.

L'exemple suivant montre un champ auquel XmlElementAttribute appliqué et la propriété IsNullable définie sur false.

public class MyClass
{
   [XmlElement(IsNullable = false)]
   public string Group;
}

Vous pouvez jeter un oeil à d'autres XmlElementAttribute pour changer les noms dans la sérialisation, etc.


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 nulles:

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;
    }

En plus de ce que Chris Taylor a écrit: si vous avez quelque chose sérialisé en tant qu'attribut, vous pouvez avoir une propriété dans 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;
}

Vous pouvez créer une fonction avec le pattern ShouldSerialize{PropertyName} qui indique à XmlSerializer s'il doit sérialiser le membre ou non.

Par exemple, si votre propriété de classe s'appelle MyNullableInt vous pourriez avoir

public bool ShouldSerializeMyNullableInt() 
{
  return MyNullableInt.HasValue;
}

Voici un exemple 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 XML suivant - Avis 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>

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;
}




xml-serialization