2016-08-18 7 views
1

하나 이상의 목록을 고유 xml 파일에 직렬화하려고합니다. 내 프로젝트가 UWP이고, 내 목록 3을 직렬화하는 것처럼 보이지만 파일이 비어있는 것으로 표시됩니다. 이전에 사용자가 코드의 일부를 도와주었습니다. 어떻게 올바르게 직렬화 할 수 있습니까?UWP에서 C# XML 직렬화

내 코드를 실행하려면 "project();"를 사용하십시오.

내 모든 코드 : 어떤 도움에 감사드립니다

<?xml version="1.0" encoding="utf-8"?> 
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <List1> 
    <Property1>1</Property1> 
    <Property2>true</Property2> 
    <Property3>false</Property3> 
    <ToAcero>0.1</ToAcero> 
    </List1> 
    <List2> 
    <Property1>true</Property1> 
    <Property2>true</Property2> 
    </List2> 
    <List3> 
    <Property1>3.564</Property1> 
    <Property2>0.215</Property2> 
    <Property3>0.7252</Property3> 
    <Property4>23.463</Property4> 
    </List3> 
</Root> 

:이 비슷한을 얻을 싶어

using Project.Common; 
using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Xml.Serialization; 
using Windows.Storage; 
using System.Threading.Tasks; 

namespace Project 
{ 
    public class All_Classes 
    { 
     public class List1 : BindableBase 
     { 
      private int _Property1; 
      public int Property1 
      { 
       get { return _Property1; } 
       set { SetProperty(ref _Property1, value); } 
      } 

      private bool _Property2; 
      public bool Property2 
      { 
       get { return _Property2; } 
       set { SetProperty(ref _Property2, value); } 
      } 

      private bool _Property3; 
      public bool Property3 
      { 
       get { return _Property3; } 
       set { SetProperty(ref _Property3, value); } 
      } 
     } 

     public class List2 : BindableBase 
     { 

      private bool _Property1; 
      public bool Property1 
      { 
       get { return _Property1; } 
       set { SetProperty(ref _Property1, value); } 
      } 

      private bool _Property2; 
      public bool Property2 
      { 
       get { return _Property2; } 
       set { SetProperty(ref _Property2, value); } 
      } 
     } 

     public class List3 : BindableBase 
     { 
      private double _Property1; 
      public double Property1 
      { 
       get { return _Property1; } 
       set { SetProperty(ref _Property1, value); } 
      } 

      private double _Property2; 
      public double Property2 
      { 
       get { return _Property2; } 
       set { SetProperty(ref _Property2, value); } 
      } 

      private double _Property3; 
      public double Property3 
      { 
       get { return _Property3; } 
       set { SetProperty(ref _Property3, value); } 
      } 

      private double _Property4; 
      public double Property4 
      { 
       get { return _Property4; } 
       set { SetProperty(ref _Property4, value); } 
      } 

     } 

     public class Values_List1 : ObservableCollection<List1> 
     { 
     } 
     public class Values_List2 : ObservableCollection<List2> 
     { 
     } 
     public class Values_List3 : ObservableCollection<List3> 
     { 
     } 

     public static class ApplicationServices 
     { 
      public static Values_List1 List1 = new Values_List1(); 
      public static Values_List2 List2 = new Values_List2(); 
      public static Values_List3 List3 = new Values_List3(); 

      static ApplicationServices() 
      { 
      } 
     } 

     public static void AddNewData() 
     { 
      ApplicationServices.List1.Add(new List1() 
      { 
       Property1 = 1, 
       Property2 = true, 
       Property3 = false, 

      }); 

      ApplicationServices.List2.Add(new List2() 
      { 
       Property1 = false, 
       Property2 = true, 
      }); 

      ApplicationServices.List3.Add(new List3() 
      { 
       Property1 = 3.564, 
       Property2 = 0.215, 
       Property3 = 0.7252, 
       Property4 = 23.463, 
      }); 
     } 

     public static async void SaveObjectToXml<T>(T objectToSave) 
     { 
      //<-----------FilePicker------------------> 
      var savePicker = new Windows.Storage.Pickers.FileSavePicker(); 
      savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.DocumentsLibrary; 
      savePicker.FileTypeChoices.Add("New File", new List<string>() { ".xml" }); 
      savePicker.SuggestedFileName = "New File"; 
      StorageFile newfile = await savePicker.PickSaveFileAsync(); 
      //<-----------FilePicker------------------> 
      //<----------------Serializacion------------------> 

      var serializer = new XmlSerializer(typeof(T)); 

      Stream stream = await newfile.OpenStreamForWriteAsync(); 


      using (stream) 
      { 
       serializer.Serialize(stream, objectToSave); 
      } 
      //<----------------Serializacion------------------> 

     } 

     public class myCompoundClass 
     { 
      public List1 List1 { get; set; } 
      public List2 List2 { get; set; } 
      public List3 List3 { get; set; } 
     } 

     public static void project() 
     { 
      myCompoundClass new_instance = new myCompoundClass(); 
      AddNewData(); 
      SaveObjectToXml(new_instance); 
     } 

    } 
} 

.

답변

1

당신은 결코 당신의 myCompoundClass 내부의 속성 값 List1 또는 List2 또는 List3 중 하나를 설정하지 :

 myCompoundClass new_instance = new myCompoundClass(); 
     AddNewData(); 
     // new_instance was not passed to AddNewData and so its properties have their default values of null. 
     SaveObjectToXml(new_instance); 

은 따라서 모든 속성은 여전히 ​​ null 될 것입니다. 이것이 XML 파일이 비어있는 이유입니다. 직렬화하기 전에 static class ApplicationServices의 데이터를 new_instance으로 옮겨야합니다.

업데이트

당신은 질문, 내가 ApplicationServices와 "new_instance"을 채울 수있는 방법? 귀하의 문제는 ApplicationServices 클래스를 직렬화하려고하지만 그것은 정적 클래스이므로 그대로 직렬화 할 수 없습니다. 제안 사항은 다음과 같습니다.

  1. 이름을 변경하십시오. List1과 같은 형식은 이 아니며이 아닙니다. 다음과 같이 제안합니다.

    public class Values1 : BindableBase // Formerly List1 
    { 
        // Contents unchanged 
    } 
    
    public class Values2 : BindableBase // Formerly List2 
    { 
        // Contents unchanged 
    } 
    
    public class Values3 : BindableBase // Formerly List3 
    { 
        // Contents unchanged 
    } 
    
    public class Values1List : ObservableCollection<Values1> 
    { 
    } 
    public class Values2List : ObservableCollection<Values2> 
    { 
    } 
    public class Values3List : ObservableCollection<Values3> 
    { 
    } 
    

    기존 이름 지정 규칙은 컬렉션이 무엇인지 아닌지에 대해 오해 할 수 있습니다.

    또한 All_Classes 클래스 내부에 중첩하지 않는 것이 좋습니다. 이렇게하면 명확성보다는 복잡성이 추가됩니다.

    [XmlRoot("Root")] 
    public class ApplicationServicesDTO 
    { 
        [XmlElement] 
        public Values1List List1 { get { return ApplicationServices.List1; } } 
    
        [XmlElement] 
        public Values2List List2 { get { return ApplicationServices.List2; } } 
    
        [XmlElement] 
        public Values3List List3 { get { return ApplicationServices.List3; } } 
    } 
    

    일부 노트 : 당신이 직렬화에 대해 다음 데이터 전송 객체를 도입, 정적 유형을 직렬화 할 수 없기 때문에

    public static class ApplicationServices 
    { 
        public static readonly Values1List List1 = new Values1List(); 
        public static readonly Values2List List2 = new Values2List(); 
        public static readonly Values3List List3 = new Values3List(); 
    
        static ApplicationServices() 
        { 
        } 
    } 
    
  2. :

  3. 정적 값 목록은 읽기 전용으로 확인 :

    • List 속성은 가져 오기 전용입니다.일반적으로 XmlSerializer은 가져 오기 전용 속성을 serialize하지 않지만 컬렉션이 미리 할당 된 경우에만 컬렉션 속성을 가져옵니다.

    • [XmlRoot("Root")]은 형식이 <Root>이라는 루트 요소로 serialize되어야 함을 나타냅니다.

    • [XmlElement]은 컬렉션 속성에 외부 컨테이너 요소가없는 요소의 반복 된 시퀀스로 serialize되어야 함을 나타냅니다.

      var new_instance = new ApplicationServicesDTO(); 
      

      을 그리고 정적 목록은 당신이 원하는 XML 형식으로 직렬화 얻을 것이다 :

지금 당신은 할 수있을 것입니다.

나중에 XML을 비 직렬화하려는 경우 ApplicationServices 내부의 기존 목록을 먼저 지울 수 있습니다. 자세한 내용은 XML Deserialization of collection property with code defaults을 참조하십시오.

+0

무엇이 잘못 되었습니까?하지만 ApplicationServices에 내 데이터를 추가해야하지만 정적이어서 인스턴스가됩니다. ApplicationServices로 "new_instance"를 채울 수있는 방법은 무엇입니까? – Julius