2009-11-10 10 views
9

Mam klasę C#, która ma 20+ właściwości ciągu. Ustawiłem około jednej czwartej wartości rzeczywistej. Chciałbym serializować klasę i uzyskać mocPomiń xsi: zero, ale nadal pokazuj pusty element podczas szeregowania w .Net

<EmptyAttribute></EmptyAttribute> 

dla nieruchomości

public string EmptyAttribute {get;set;} 

Nie chcę wyjście być

<EmptyAttribute xsi:nil="true"></EmptyAttribute> 

Używam następujące klasy

public class XmlTextWriterFull : XmlTextWriter 
{ 
    public XmlTextWriterFull(string filename) : base(filename,Encoding.UTF8) { } 

    public override void WriteEndElement() 
    { 
     base.WriteFullEndElement(); 
     base.WriteRaw(Environment.NewLine); 
    } 
} 

dzięki czemu Mogę uzyskać pełne tagi. Po prostu nie wiem jak pozbyć się xsi: zero.

+0

Myślę, że to jest dokładnie to, czego potrzebuję, ale twoje pytanie jest niekompletne. Zamiast '' chciałbyś otrzymać ''? Jeśli znajdę odpowiedź, wrócę! – njplumridge

+0

Poniżej zamieszczam moją odpowiedź, sprawdź to i zagłosuj, jeśli ci pomoże, lub jeśli znajdziesz lepszy sposób, opublikuj i daj mi znać. –

Odpowiedz

-5

Właściwie to udało mi się to rozgryźć. Wiem, że trochę hack, w pewnym sensie, ale to jak mam go do pracy

System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(header.GetType()); 
     XmlTextWriterFull writer = new XmlTextWriterFull(FilePath); 
     x.Serialize(writer, header); 
     writer.Flush(); 
     writer.BaseStream.Dispose(); 
     string xml = File.ReadAllText(FilePath); 
     xml = xml.Replace(" xsi:nil=\"true\"", ""); 
     File.WriteAllText(FilePath, xml); 

nadzieję, że to pomoże ktoś inny się

+1

-1 ... To jest okropny sposób radzenia sobie z XMLem, unikaj takich manipulacji łańcuchami. Jeśli naprawdę chcesz usunąć atrybuty - użyj odpowiedniego interfejsu API XML ... –

+1

@AlexeiLevenkov: Głównym celem pytania było znalezienie najlepszego sposobu, aby to zrobić - prawdopodobnie dlatego, że nie wiedział, jak korzystać z API, aby osiągnąć to. Trochę trudny do krytykowania, że ​​go nie używa. Lepszą odpowiedzią byłoby dostarczenie odpowiedzi, która demonstruje prawidłowe użycie interfejsu API XML. –

+3

@ChrisRogers - istnieje już dobra odpowiedź - dlatego komentarz jest tutaj po to, aby oderwać ludzi od tego. Manipulowanie ciągiem nie jest dobrym podejściem do obsługi XML. –

12

drogę do mają XmlSerializer serializacji właściwość bez dodawania xsi:nil="true" atrybut jest pokazany poniżej:

[XmlRoot("MyClassWithNullableProp", Namespace="urn:myNamespace", IsNullable = false)] 
public class MyClassWithNullableProp 
{ 
    public MyClassWithNullableProp() 
    { 
     this._namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { 
      new XmlQualifiedName(string.Empty, "urn:myNamespace") // Default Namespace 
     }); 
    } 

    [XmlElement("Property1", Namespace="urn:myNamespace", IsNullable = false)] 
    public string Property1 
    { 
     get 
     { 
      // To make sure that no element is generated, even when the value of the 
      // property is an empty string, return null. 
      return string.IsNullOrEmpty(this._property1) ? null : this._property1; 
     } 
     set { this._property1 = value; } 
    } 
    private string _property1; 

    // To do the same for value types, you need a "helper property, as demonstrated below. 
    // First, the regular property. 
    [XmlIgnore] // The serializer won't serialize this property properly. 
    public int? MyNullableInt 
    { 
     get { return this._myNullableInt; } 
     set { this._myNullableInt = value; } 
    } 
    private int? _myNullableInt; 

    // And now the helper property that the serializer will use to serialize it. 
    [XmlElement("MyNullableInt", Namespace="urn:myNamespace", IsNullable = false)] 
    public string XmlMyNullableInt 
    { 
     get 
     { 
      return this._myNullableInt.HasValue? 
       this._myNullableInt.Value.ToString() : null; 
     } 
     set { this._myNullableInt = int.Parse(value); } // You should do more error checking... 
    } 

    // Now, a string property where you want an empty element to be displayed, but no 
    // xsi:nil. 
    [XmlElement("MyEmptyString", Namespace="urn:myNamespace", IsNullable = false)] 
    public string MyEmptyString 
    { 
     get 
     { 
      return string.IsNullOrEmpty(this._myEmptyString)? 
       string.Empty : this._myEmptyString; 
     } 
     set { this._myEmptyString = value; } 
    } 
    private string _myEmptyString; 

    // Now, a value type property for which you want an empty tag, and not, say, 0, or 
    // whatever default value the framework gives the type. 
    [XmlIgnore] 
    public float? MyEmptyNullableFloat 
    { 
     get { return this._myEmptyNullableFloat; } 
     set { this._myEmptyNullableFloat = value; } 
    } 
    private float? _myEmptyNullableFloat; 

    // The helper property for serialization. 
    public string XmlMyEmptyNullableFloat 
    { 
     get 
     { 
      return this._myEmptyNullableFloat.HasValue ? 
       this._myEmptyNullableFloat.Value.ToString() : string.Empty; 
     } 
     set 
     { 
      if (!string.IsNullOrEmpty(value)) 
       this._myEmptyNullableFloat = float.Parse(value); 
     } 
    } 

    [XmlNamespaceDeclarations] 
    public XmlSerializerNamespaces Namespaces 
    { 
     get { return this._namespaces; } 
    } 
    private XmlSerializerNamespaces _namespaces; 
} 

Teraz stwórz instancję tej klasy i serializuj ją.

// I just wanted to show explicitly setting all the properties to null... 
MyClassWithNullableProp myClass = new MyClassWithNullableProp() { 
    Property1 = null, 
    MyNullableInt = null, 
    MyEmptyString = null, 
    MyEmptyNullableFloat = null 
}; 

// Serialize it. 
// You'll need to setup some backing store for the text writer below... 
// a file, memory stream, something... 
XmlTextWriter writer = XmlTextWriter(...) // Instantiate a text writer. 

XmlSerializer xs = new XmlSerializer(typeof(MyClassWithNullableProp), 
    new XmlRootAttribute("MyClassWithNullableProp") { 
     Namespace="urn:myNamespace", 
     IsNullable = false 
    } 
); 

xs.Serialize(writer, myClass, myClass.Namespaces); 

Po pobraniu zawartości XmlTextWriter, trzeba mieć następujący wynik:

<MyClassWithNullableProp> 
    <MyEmptyString /> 
    <MyEmptyNullableFloat /> 
</MyClassWithNullableProp> 

Mam nadzieję, że jasno pokazuje, jak wbudowany Framework XmlSerializer może być użyta do serializacji właściwości pusty element, nawet jeśli właściwość ma wartość NULL (lub jakąś inną wartość, której nie chcesz serializować). Ponadto pokazałem, jak upewnić się, że właściwości null nie są w ogóle serializowane. Należy pamiętać, że jeśli zastosujemy wartość XmlElementAttribute i ustawimy dla tego atrybutu wartość IsNullable na true, wówczas ta właściwość zostanie przekształcona do postaci szeregowej z atrybutem xsi:nil, gdy właściwość ta będzie równa null (chyba że zostanie zmieniona gdzie indziej).

+1

To naprawdę doskonały sposób na zapewnienie generowania pustych elementów. Mam już gotowy kod serializacji. Interesowało mnie tylko pusty element dla właściwości string.Jedyne, co musiałem zrobić, to dodać jedną linijkę do właściwości, aby sprawdzić String.IsNullOrEmpty i zwrócić String.Empty jeśli true. Twoje zdrowie!! –