xmlelement - xml element with attribute c#




Sérialisation Xml-Masquer les valeurs NULL (5)

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>

Dans mon cas, les variables / éléments nullables étaient tous du type String. Donc, j'ai simplement effectué une vérification et leur a assigné une chaîne.Empty en cas de NULL. De cette façon, je me suis débarrassé des attributs inutiles nil et xmlns (p3: nil = "true" xmlns: p3 = "http://www.w3.org/2001/XMLSchema-instance)

// Example:

myNullableStringElement = varCarryingValue ?? string.Empty

// OR

myNullableStringElement = myNullableStringElement ?? string.Empty

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

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

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