Xml序列化 – 隐藏空值

当使用标准的.NET Xml Serializer时,有没有什么办法可以隐藏所有的空值? 以下是我class的输出示例。 如果它们设置为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> 

您可以使用ShouldSerialize{PropertyName}模式创build一个函数,告诉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); 

结果在下面的XML – 注意没有年龄

 <Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Name>Chris</Name> </Person> 

另外Chris Taylor写道:如果你有序列化为属性的东西,你可以在名为{PropertyName}Specified类上有一个属性, {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; } 

在我的情况下,可为空的variables/元素都是stringtypes。 所以,我只是执行一个检查,并将其分配给string.Empty在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 

我更喜欢创build自己的XML,没有自动生成的标签。 在这我可以忽略创build空值的节点:

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