it-swarm.dev

Xml serializace - Skrýt hodnoty null

Při použití standardního rozhraní .NET Xml Serializer existuje nějaký způsob, jak mohu skrýt všechny hodnoty null? Níže je příklad výstupu mé třídy. Nechci na výstupu nullable celá čísla, pokud jsou nastaveny na hodnotu null.

Aktuální výstup 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>

Co chci:

<?xml version="1.0" encoding="utf-8"?>
<myClass>
   <myOtherInt>-1</myOtherInt>
</myClass>
106
GuruMeditation

Můžete vytvořit funkci se vzorem ShouldSerialize{PropertyName}, který řekne XmlSerializer, pokud má člen serializovat nebo ne.

Pokud se například vlastnost třídy nazývá MyNullableInt, můžete mít

public bool ShouldSerializeMyNullableInt() 
{
  return MyNullableInt.HasValue;
}

Zde je úplný vzorek

public class Person
{
  public string Name {get;set;}
  public int? Age {get;set;}
  public bool ShouldSerializeAge()
  {
    return Age.HasValue;
  }
}

Serializován s následujícím kódem

Person thePerson = new Person(){Name="Chris"};
XmlSerializer xs = new XmlSerializer(typeof(Person));
StringWriter sw = new StringWriter();
xs.Serialize(sw, thePerson);

Výsledky v následujícím XML - Všimněte si, že neexistuje žádný věk

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

Kromě toho, co napsal Chris Taylor: pokud máte něco serializovaného jako atribut, můžete mít ve své třídě vlastnost s názvem {PropertyName}Specified, která bude kontrolovat, zda má být serializována. V kódu:

public class MyClass
{
    [XmlAttribute]
    public int MyValue;

    [XmlIgnore]
    public bool MyValueSpecified;
}
30
Daniel Rose

Existuje vlastnost nazvaná XmlElementAttribute.IsNullable 

Pokud je vlastnost IsNullable nastavena na hodnotu true, atribut xsi: nil je generován pro členy třídy, kteří byli nastaveni na hodnotu null. 

Následující příklad ukazuje pole s XmlElementAttribute aplikovaným na něj a vlastnost IsNullable nastavenou na hodnotu false.

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

Můžete se podívat na další XmlElementAttribute pro změnu názvů v serializaci atd.

22
JPBlanc

Můžete definovat některé výchozí hodnoty a zamezit serializaci polí.

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

    [XmlArray, DefaultValue(null)]
    List<string> data;
10
MichaelSo
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;
}
1
Rauld

V mém případě byly nulovatelné proměnné/elementy všechny typu String. Takže jsem prostě provedl kontrolu a přidělil jim řetězec.Empty v případě NULL. Tímto způsobem jsem se zbavil zbytečných atributů nil a xmlns (p3: nil = "true" xmlns: p3 = "http://www.w3.org/2001/XMLSchema-instance)

// Example:

myNullableStringElement = varCarryingValue ?? string.Empty

// OR

myNullableStringElement = myNullableStringElement ?? string.Empty
0
Sagar

Dávám přednost vytváření vlastního XML bez tagů generovaných automaticky. V tomto můžu ignorovat vytváření uzlů s hodnotami 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;
    }
0
Durga Nunna