[C#] Xml 직렬화-null 값 숨기기

표준 .NET Xml Serializer를 사용할 때 모든 null 값을 숨길 수있는 방법이 있습니까? 아래는 내 수업의 출력 예입니다. nullable 정수가 null로 설정되어 있으면 nullable 정수를 출력하고 싶지 않습니다.

현재 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}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>


답변

Chris Taylor가 쓴 것 외에도 속성 {PropertyName}Specified으로 직렬화 된 것이 있으면 클래스의 속성을 직렬화 해야하는지 제어 할 수 있습니다. 코드에서 :

public class MyClass
{
    [XmlAttribute]
    public int MyValue;

    [XmlIgnore]
    public bool MyValueSpecified;
}


답변

라는 속성이 있습니다 XmlElementAttribute.IsNullable

IsNullable 속성이 true로 설정되면 null 참조로 설정된 클래스 멤버에 대해 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;


답변

자동 생성 태그가없는 고유 한 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;
    }


답변

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 변수 / 요소는 모두 String 유형이었습니다. 그래서 단순히 검사를 수행하고 문자열을 할당했습니다 .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