Xml序列化 - 隐藏空值

时间:2011-04-28 12:22:29

标签: c# .net xml-serialization

使用标准.NET Xml Serializer时,有什么办法可以隐藏所有空值吗?以下是我班级输出的一个例子。如果它们被设置为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 个答案:

答案 0 :(得分:225)

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

答案 1 :(得分:31)

除了Chris Taylor所写的内容之外:如果您将某些内容序列化为属性,则可以在类{PropertyName}Specified上创建一个属性来控制它是否应该序列化。在代码中:

public class MyClass
{
    [XmlAttribute]
    public int MyValue;

    [XmlIgnore]
    public bool MyValueSpecified;
}

答案 2 :(得分:22)

它存在一个名为XmlElementAttribute.IsNullable

的属性

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

以下示例显示应用了XmlElementAttribute的字段,并将IsNullable属性设置为false。

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

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

答案 3 :(得分:10)

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

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

在我的例子中,可空变量/元素都是String类型。所以,我只是执行了一个检查,并在NULL的情况下为它们分配了string.Empty。这样我就摆脱了不必要的nil和xmlns属性(p3:nil =“true”xmlns:p3 =“http://www.w3.org/2001/XMLSchema-instance)

// Example:

myNullableStringElement = varCarryingValue ?? string.Empty

// OR

myNullableStringElement = myNullableStringElement ?? string.Empty

答案 6 :(得分:0)

我更喜欢在没有自动生成标签的情况下创建自己的xml。在此我可以忽略创建具有空值的节点:

 JSONArray response;
        try {
            response = new JSONArray(res);
            for (int i = 0; i < response.length(); i++) {
                JSONArray insideJSONArray = response.getJSONArray(i);
                JSONObject jsonObject = insideJSONArray.getJSONObject(0);
                String mobileNumber = jsonObject.getString("mobileNumber");
                Log.e("TAG", "mobileNumber: " + mobileNumber);
                String contactUserId = jsonObject.getString("contactUserId");
                Log.e("TAG", "mobileNumber: " + contactUserId);
                JSONArray userEwallets = jsonObject.getJSONArray("userEwallets");
                for (int j = 0; j < userEwallets.length(); j++) {
                    JSONObject ewalletObject = userEwallets.getJSONObject(j);
                    final String accountNumber = ewalletObject.getString("accountNumber");
                    Log.e("accountNumber ", accountNumber);

                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }