web-dev-qa-db-fra.com

Sérialisation XML - Masquer les valeurs NULL

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>
106
GuruMeditation

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>
222
Chris Taylor

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;
}
30
Daniel Rose

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.

22
JPBlanc

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;
10
MichaelSo
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;
}
1
Rauld

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
0
Sagar

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;
    }
0
Durga Nunna