XML-сериализация-скрыть значения null
при использовании стандартного .NET Xml сериализатора, есть ли способ скрыть все нулевые значения? Ниже приведен пример вывода моего класса. Я не хочу выводить nullable целые числа, если они установлены в null.
текущая вывода информации в формате XML:
<?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>
что хочется:
<?xml version="1.0" encoding="utf-8"?>
<myClass>
<myOtherInt>-1</myOtherInt>
</myClass>
7 ответов:
вы можете создать функцию с шаблоном
ShouldSerialize{PropertyName}который сообщает XmlSerializer, если он должен сериализовать член или нет.например, если свойство класса называется
MyNullableIntмог быpublic bool ShouldSerializeMyNullableInt() { return MyNullableInt.HasValue; }вот пример
public class Person { public string Name {get;set;} public int? Age {get;set;} public bool ShouldSerializeAge() { return Age.HasValue; } }сериализуется с помощью следующего кода
Person thePerson = new Person(){Name="Chris"}; XmlSerializer xs = new XmlSerializer(typeof(Person)); StringWriter sw = new StringWriter(); xs.Serialize(sw, thePerson);результаты в followng XML-обратите внимание, что нет возраста
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Name>Chris</Name> </Person>
В дополнение к тому, что написал Крис Тейлор: если у вас есть что-то сериализованное в качестве атрибута, вы можете иметь свойство в своем классе с именем
{PropertyName}Specifiedдля управления, если он должен быть сериализован. В коде:public class MyClass { [XmlAttribute] public int MyValue; [XmlIgnore] public bool MyValueSpecified; }
существует свойство под названием
XmlElementAttribute.IsNullableесли свойство IsNullable имеет значение true, атрибут xsi:nil создается для членов класса, для которых задана нулевая ссылка.
в следующем примере показано поле с
XmlElementAttributeприменяется к нему, и свойство IsNullable имеет значение false.public class MyClass { [XmlElement(IsNullable = false)] public string Group; }вы можете посмотреть на других
XmlElementAttributeдля изменения имен в сериализации и т. д.
вы можете определить некоторые значения по умолчанию, и это предотвращает сериализацию полей.
[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; }
в моем случае nullable переменные / элементы были все строкового типа. Итак, я просто выполнил проверку и назначил им строку.Пусто в случае NULL. Таким образом, я избавился от ненужных атрибутов nil и xmlns (p3:nil= "true" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance)
// Example: myNullableStringElement = varCarryingValue ?? string.Empty // OR myNullableStringElement = myNullableStringElement ?? string.Empty
Я предпочитаю создавать свой собственный xml без автоматически генерируемых тегов. В этом я могу игнорировать создание узлов с нулевыми значениями:
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; }
Comments