2009-11-10 24 views
9

我有一個C#類,具有20 +字符串屬性。我將其中的四分之一設置爲實際值。我想序列化類,並得到抑制xsi:nil,但仍然顯示在.NET中序列化時顯示空元素

<EmptyAttribute></EmptyAttribute> 

的輸出屬性

public string EmptyAttribute {get;set;} 

我不希望輸出爲

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

我使用下面的類

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

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

這樣我可以得到完整的標籤。我只是不知道如何擺脫xsi:nil。

+0

我認爲這正是我所需要的,但您的問題並不完整。而不是''你想要''?如果我找到答案,我會回來! – njplumridge 2010-03-24 17:28:39

+0

我在下面發佈了我的答案,並將其發佈出來,如果它可以幫助您或者如果您找到了更好的方式發佈並讓我知道。 – 2010-03-24 19:15:11

回答

-5

我實際上能夠弄清楚這一點。我知道它有點在某些方面是黑客攻擊的,但是這是我得到它的工作

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

希望這可以幫助其他人了

+1

-1 ...這是處理XML的可怕方法,請避免這種字符串操作。如果你真的想剝離屬性 - 使用正確的XML API ... – 2013-08-28 03:00:17

+1

@AlexeiLevenkov:問題的全部目的是找出最好的方法來做到這一點 - 大概是因爲他不知道如何使用API​​來實現它。有點苛刻批評他不使用它。 更好的迴應是提供一個能夠正確使用XML API的答案。 – 2013-09-03 03:10:19

+3

@ChrisRogers--已經有了很好的答案 - 所以評論在這裏引導人們遠離這一點。字符串操作幾乎不是處理XML的好方法。 – 2013-09-03 04:20:43

12

的方式有XmlSerializer連載的屬性不添加xsi:nil="true"屬性如下所示:

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

現在,實例化這個類並對其進行序列化。

// 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); 

檢索XmlTextWriter的內容後,你應該有以下的輸出:

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

我希望這清楚地說明內置.NET框架XmlSerializer可用於性能序列化一個空元素,即使屬性值爲空(或者其他值不想序列化)。另外,我已經展示瞭如何確保null屬性完全沒有序列化。有一點需要注意,如果您應用XmlElementAttribute並將該屬性的IsNullable屬性設置爲true,那麼當屬性爲null(除非在其他位置重寫)時,該屬性將與xsi:nil屬性串行化。

+1

這確實是確保生成空元素的絕佳方式。我已經準備好了序列化代碼。我只對string屬性的空元素感興趣。我所要做的只是在屬性中添加一個班輪來檢查String.IsNullOrEmpty,如果爲true,則返回String.Empty。乾杯!! – 2016-02-07 23:45:01