XML 序列化——隐藏空值

使用标准时。NETXMLSerializer,有没有什么方法可以隐藏所有的空值?下面是我的类的输出示例。如果可空整数被设置为 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>
120031 次浏览

您可以使用模式 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);

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

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

它存在一个名为 XmlElementAttribute.IsNullable的属性

如果 IsNullable 属性设置为 true,则为设置为 null 引用的类成员生成 xsi: nil 属性。

下面的示例显示一个字段,该字段应用了 XmlElementAttribute,IsNullable 属性设置为 false。

public class MyClass
{
[XmlElement(IsNullable = false)]
public string Group;
}

您可以查看其他 XmlElementAttribute,以便在序列化中更改名称等。

除此之外,Chris Taylor 还写道: 如果将某些内容序列化为属性,那么可以在类上设置一个名为 {PropertyName}Specified的属性来控制它是否应该被序列化。代码:

public class MyClass
{
[XmlAttribute]
public int MyValue;


[XmlIgnore]
public bool MyValueSpecified;
}
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;
}

您可以定义一些默认值,它可以防止字段被序列化。

    [XmlElement, DefaultValue("")]
string data;


[XmlArray, DefaultValue(null)]
List<string> data;

在我的例子中,可空变量/元素都是 String 类型的。因此,我只是执行了一个检查并分配了它们的字符串。如果为空,则为空。这样我就去掉了不必要的 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。在这里,我可以忽略创建具有 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;
}