c# - serializar - Serialización Xml-Ocultar valores nulos
system xml serialization xmlserializer vb net (7)
Además de lo que escribió Chris Taylor: si tienes algo serializado como atributo, puedes tener una propiedad en tu clase llamada {PropertyName}Specified
para controlar si se debe serializar. En codigo:
public class MyClass
{
[XmlAttribute]
public int MyValue;
[XmlIgnore]
public bool MyValueSpecified;
}
Al usar un serializador .ml Xml estándar, ¿hay alguna manera de ocultar todos los valores nulos? El siguiente es un ejemplo de la salida de mi clase. No quiero dar salida a los enteros nulables si están configurados como nulos.
Salida Xml actual:
<?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>
Lo que quiero:
<?xml version="1.0" encoding="utf-8"?>
<myClass>
<myOtherInt>-1</myOtherInt>
</myClass>
En mi caso, las variables / elementos que aceptan nulos son todo tipo de cadena. Entonces, simplemente realicé un cheque y les asigné una cadena. Vacío en caso de NULL. De esta forma me deshice de los atributos nil y xmlns innecesarios (p3: nil = "true" xmlns: p3 = "http://www.w3.org/2001/XMLSchema-instance)
// Example:
myNullableStringElement = varCarryingValue ?? string.Empty
// OR
myNullableStringElement = myNullableStringElement ?? string.Empty
Existe una propiedad llamada XmlElementAttribute.IsNullable
Si la propiedad IsNullable se establece en true, el atributo xsi: nil se genera para los miembros de la clase que se han establecido en una referencia nula.
El siguiente ejemplo muestra un campo con XmlElementAttribute
aplicado a él, y la propiedad IsNullable establecida en falso.
public class MyClass
{
[XmlElement(IsNullable = false)]
public string Group;
}
Puede echarle un vistazo a otro XmlElementAttribute
para cambiar nombres en serialización, etc.
Prefiero crear mi propio xml sin etiquetas generadas automáticamente. En esto puedo ignorar la creación de nodos con valores nulos:
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;
}
Puede crear una función con el patrón ShouldSerialize{PropertyName}
que le dice al XmlSerializer si debe serializar el miembro o no.
Por ejemplo, si su propiedad de clase se llama MyNullableInt
podría tener
public bool ShouldSerializeMyNullableInt()
{
return MyNullableInt.HasValue;
}
Aquí hay una muestra completa
public class Person
{
public string Name {get;set;}
public int? Age {get;set;}
public bool ShouldSerializeAge()
{
return Age.HasValue;
}
}
Serializado con el siguiente código
Person thePerson = new Person(){Name="Chris"};
XmlSerializer xs = new XmlSerializer(typeof(Person));
StringWriter sw = new StringWriter();
xs.Serialize(sw, thePerson);
Resultados en el siguiente XML - Aviso que no hay edad
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Chris</Name>
</Person>
Puede definir algunos valores predeterminados e impide que los campos se serialicen.
[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;
}