2009-11-10 2 views
9

20 개 이상의 문자열 속성을 가진 C# 클래스가 있습니다. 나는 그 중 4 분의 1을 실제 가치로 설정했습니다. 나는 출력 내가 다음 클래스를 사용하고xsi : nil을 표시하지 않고 .Net에서 일련 번호를 지정할 때 빈 요소를 계속 표시합니다.

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

싶지 않아

public string EmptyAttribute {get;set;} 

속성에 대한

<EmptyAttribute></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

+0

나는 아래의 나의 대답을 올리고 체크 아웃했다. 투표가 도움이된다면, 또는 더 좋은 방법을 찾고 나에게 알려주면 투표 할 수있다. –

답변

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

희망을 작동하는 데있어이이 xsi:nil="true"를 추가하지 않고 XmlSerializer 직렬화에게 재산을 가지고 밖으로

+1

-1 ... 이것은 XML을 다루는 끔찍한 방법으로 그러한 문자열 조작을 피하십시오. 속성을 제거하고 싶다면 적절한 XML API를 사용하십시오. –

+1

@AlexeiLevenkov : 질문의 전체 목적은이를 수행하는 가장 좋은 방법을 찾는 것입니다. 아마도 API를 사용하여 그것. 사용하지 않는 것을 비판하는 것은 가혹한 것입니다. 더 나은 응답은 XML API의 올바른 사용을 입증하는 대답을 제공하는 것입니다. –

+3

@ChrisRogers - 이미 좋은 대답이 있습니다. 그래서 사람들이 이것을 형성하도록 조종하는 의견이 있습니다. 문자열 조작은 XML을 처리하는 좋은 방법이 아닙니다. –

12

방법 다른 사람의 도움 방법입니다 속성은 아래에 표시됩니다.

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

이제이 클래스를 인스턴스화하고 일련 번호를 지정하십시오.

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

난이 명확하게 내장 된 .NET 프레임 워크 XmlSerializer가 속성을 직렬화하는 데 사용할 수있는 방법을 보여줍니다 희망 :

// 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의 내용을 검색 한 후, 다음과 같은 출력을 가져야한다 속성 값이 null이거나 (직렬화하고 싶지 않은 다른 값이더라도) 빈 요소. 또한 null 속성이 직렬화되지 않도록하는 방법을 보여 드렸습니다. 한 가지주의 할 점은 XmlElementAttribute을 적용하고 해당 속성의 IsNullable 속성을 true으로 설정하면 속성이 null 일 때 xsi:nil 속성으로 직렬화됩니다 (다른 곳에서 재정의되지 않은 경우).

+1

이것은 빈 요소가 생성되도록하는 훌륭한 방법입니다. 이미 직렬화 코드를 준비했습니다. 문자열 속성에 대한 빈 요소에만 관심이있었습니다.String.IsNullOrEmpty를 검사하고 String.Empty를 true로 반환하려면 속성에 하나의 라이너를 추가하면됩니다. 건배!! –