2012-03-23 2 views
0

제 XML 직렬화를 깔끔하게하는 것에 대한 또 다른 질문이 있습니다. 올바르게 진행할 수 없습니다.여러 클래스에서 XML 생성?

namespace SMCProcessMonitor 
{ 
[Serializable()] 
[XmlRoot("Email-Settings")] 
    public class Config 
{  
     [XmlElement("Recipient")] 
     public string recipient; 
     [XmlElement("Server-port")] 
     public int serverport; 
     [XmlElement("Username")] 
     public string username; 
     [XmlElement("Password")] 
     public string password; 
     [XmlElement("Program")] 
     public List<Programs> mPrograms = new List<Programs>(); 
     public string serialId; 
    } 

    public class Email 
    { 

      public string Recipient 
      { 
       get 
       { 
        return SMCProcessMonitor.ConfigManager.mConfigurations.recipient; 
       } 
       set 
       { 
        SMCProcessMonitor.ConfigManager.mConfigurations.recipient = value; 
       } 
      } 

      public int ServerPort 
      { 
       get 
       { 
        return SMCProcessMonitor.ConfigManager.mConfigurations.serverport; 
       } 
       set 
       { 
        SMCProcessMonitor.ConfigManager.mConfigurations.serverport = value; 
       } 
      } 
      public string Username 
      { 
       get 
       { 
        return SMCProcessMonitor.ConfigManager.mConfigurations.username; 
       } 
       set 
       { 
        SMCProcessMonitor.ConfigManager.mConfigurations.username = value; 
       } 
      } 
     public string Password { get; set; } 

    } 
     [Serializable()] 
    public class Programs 
{ 
     [XmlElement("Filename")] public string mFileName { get; set; } 
     [XmlElement("Filepath")]public string mFilePath { get; set; } 
} 

     public class Database 
     { 
      public string mSerial { get; set; } 
     } 
     } 

가 이상적으로 내가하고 싶은 것은 너무

<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<email-settings> 
    <Recipient>sadh</Recipient> 
    <Server-port>23</Server-port> 
    <Username>lkms</Username> 
    <Password>kmkdvm</Password> 
</email-settings> 
<Program> 
    <Filename>MerlinAlarm.exe</Filename> 
    <Filepath>D:\Merlin\Initsys\Merlin\Bin\MerlinAlarm.exe</Filepath> 
</Program> 
<database-settings> 
    <serialId>1</serialId> 
</database-settings> 
</Config> 

그러나처럼,이 세 가지 클래스 (이메일 설정, 데이터베이스 및 프로그램) 자신의 태그가 각이 있습니다 : 다음과 같이 내 설정 파일입니다 대신 나는이 유사한 무언가를 얻을 :

<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<Recipient>blah</Recipient> 
<Server-port>1111</Server-port> 
<Username>blah</Username> 
<Password>blah</Password> 
<Program> 
<Filename>chrome.exe</Filename> 
<Filepath> 
C:\Users\Shane\AppData\Local\Google\Chrome\Application\chrome.exe 
</Filepath> 
</Program> 
<serialId>1234</serialId> 
</Config> 

등이 귀찮게하지만,이 지금 내 너트를하고있다 그리고 난 here..can 누락 몇 가지 근본적인 논리는 사람이 좀 페이지를 줄이 확실 메신저가 될 죄송합니다 oint는 위에서 지정한 형식으로이 XML을 가져 오는 방법을 알려줍니다. 미리 감사드립니다, 셰인.

편집 : 내 직렬화 클래스.

namespace SMCProcessMonitor 
{ 
public class ShanesXMLserializer 
{ 
    private string mFileAndPath; 
    public Config mConfigurations = null; 
    public Config mConfigurationsProgram = null; 



    public ShanesXMLserializer(string inFileAndPath) 
    { 
     mFileAndPath = inFileAndPath; 
     mConfigurations = new Config(); 

    } 

    public bool Write() 
    { 
     try 
     { 
      XmlSerializer x = new XmlSerializer(mConfigurations.GetType()); 
      StreamWriter writer = new StreamWriter(mFileAndPath); 
      x.Serialize(writer, mConfigurations); 
      writer.Close(); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Exception found while writing: " + ex.Message); 
     }; 

     return false; 
    } 

    public bool Read() 
    { 
     try 
     { 
      XmlSerializer x = new XmlSerializer(typeof(Config)); 
      StreamReader reader = new StreamReader(mFileAndPath); 
      mConfigurations = (Config)x.Deserialize(reader); 
      reader.Close(); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Exception found while reading: " + ex.Message); 
     }; 

     return false; 
    } 

    public Config GetConfigEmail 
    { 
     get 
     { 
      return mConfigurations; 
     } 
    } 


} 

}

편집 2 : 나의 새로운 설정 파일 : @Craig -이 설정 파일을 사용하고, 당신이 말한하지만 메신저는 여전히 원하는 XML을받지처럼, 뒤에 표시 내 config 클래스.

  using System; 
      using System.Collections.Generic; 
      using System.Linq; 
      using System.Xml.Serialization; 
      using System.Text; 

네임 스페이스 SMCProcessMonitor { [직렬화()]

 public class Config 
{  

     public string recipient; 
     public int serverport; 
     public string username; 
     public string password; 
     public List<Programs> mPrograms = new List<Programs>(); 
     public string serialId; 
    [XmlElement("email-settings")] 
     public Email Email { get; set; } 
     public Programs Programs { get; set; } 
    [XmlElement("database-settings")] 
     public Database Database { get; set; } 


    } 

    public class Email 
    { 
     [XmlElement("Recipient")] 
     public string Recipient { get; set; } 
      [XmlElement("Server-port")] 
     public int ServerPort { get; set; } 
     [XmlElement("Username")] 
     public string Username { get; set; } 
     [XmlElement("Password")] 
     public string Password { get; set; } 

    } 
     [Serializable()] 
    public class Programs 
    { 
     [XmlElement("Filename")] public string mFileName { get; set; } 
     [XmlElement("Filepath")]public string mFilePath { get; set; } 
    } 

    public class Database 
    { 
     [XmlElement("SerialID")] 
     public string mSerial { get; set; } 
    } 
    } 

하지만 난 여전히 점점 오전 :

<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <recipient>shane</recipient> 
    <serverport>23</serverport> 
    <username>oid</username> 
    <password>jidj</password> 
    <mPrograms/> 
    </Config> 
+0

직렬화에 사용하는 코드 섹션을 작성할 수 있습니까? – daryal

+0

내 직렬화 코드는 다음과 같습니다. 이제는 "개체 참조가 개체의 인스턴스로 설정되지 않았습니다"라는 말을 쓰면서 오류가 발생합니다. 변수를 해당 클래스로 이동 한 이후로 말입니다. –

+0

@ Shane'Shamus'Coulter는 질문에 추가 한 직렬화 코드를 사용하여 내가 제공 한'class' 수정을 사용하여 원하는 XML을 출력합니다. 그것을 테스트하기 위해, 당신은 내 답변에서 클래스들을 복사하고,'Config' 객체를 채우고 당신이 게시 한 직렬화 코드를 통해 그것을 실행할 수 있습니다. 당신이 변경해야 할 유일한 것은 귀하의 재산 취득자와 세터입니다. – Craig

답변

1

이 당신에게 원하는 출력 줄 것입니다 :

public class Config 
{ 
    [XmlElement("email-settings")] 
    public Email Email { get; set; } 

    public Program Program { get; set; } 

    [XmlElement("database-settings")] 
    public Database Database { get; set; } 
} 

public class Email 
{ 
    public string Recipient { get; set; } 

    [XmlElement("Server-port")] 
    public int ServerPort { get; set; } 

    public string Username { get; set; } 
    public string Password { get; set; } 
} 

public class Program 
{ 
    public string Filename { get; set; } 

    public string Filepath { get; set; } 
} 

public class Database 
{ 
    public string serialId { get; set; } 
} 

다음은 콘솔 응용 프로그램으로 개체를 파일로 serialize하고 찾고있는 정확한 XML을 생성합니다. 콘솔 응용 프로그램에 복사하여 붙여 넣기 만하면됩니다.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Serialization; 
using System.IO; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var config = new Config 
      { 
       Email = new Email 
       { 
        Recipient = "sadh", 
        ServerPort = 23, 
        Username = "lkms", 
        Password = "kmkdvm" 
       }, 
       Program = new Programs 
       { 
        Filename = "MerlinAlarm.exe", 
        Filepath = @"D:\Merlin\Initsys\Merlin\Bin\MerlinAlarm.exe" 
       }, 
       Database = new Database 
       { 
        serialId = "1" 
       } 
      }; 

      XmlSerializer serializer = new XmlSerializer(typeof(Config)); 

      var textWriter = new StreamWriter(@"C:\config.xml"); 
      serializer.Serialize(textWriter, config); 
      textWriter.Close(); 

      Console.Read(); 
     } 
    } 

    #region [Classes] 

    public class Config 
    { 
     [XmlElement("email-settings")] 
     public Email Email { get; set; } 

     public Programs Program { get; set; } 

     [XmlElement("database-settings")] 
     public Database Database { get; set; } 
    } 

    public class Email 
    { 
     public string Recipient { get; set; } 

     [XmlElement("Server-port")] 
     public int ServerPort { get; set; } 

     public string Username { get; set; } 
     public string Password { get; set; } 
    } 

    public class Programs 
    { 
     public string Filename { get; set; } 

     public string Filepath { get; set; } 
    } 

    public class Database 
    { 
     public string serialId { get; set; } 
    } 

    #endregion 
} 
+0

선언을 해당 클래스에 추가해야합니까, 아니면 구성에 남겨 두어야합니까? –

+0

@ Shane'Shamus'Coulter가 그들을'Config' 클래스에 남겨 둡니다. 귀하의 질문에 언급 된 형식의 XML이 제공됩니다. 귀하의 질문에, 당신은 당신의'Config'' 클래스'에'List '을 가지고 있지만 그것은 당신이 제공 한 원하는 XML 출력에 나타나지 않습니다. – Craig

+0

편집 2를 참조하십시오. –

0

단순함 및 유지 관리를 위해 여기에 완전히 옆으로 접근하는 방법을 제안합니다.

원본 XML 파일을 가져 와서 XSD 스키마를 생성하면 어떻게됩니까? 예를 들어

:

xsd.exe MyXMLFile1.xml 

이는 XML 스키마 파일 (MyXMLFile1.xsd)을 생성합니다. 스키마를 가지고 (다시 xsd.exe를 사용하여) 클래스를 생성 :이 향후 사용할 수있는 보장 직렬화 POCO를 생성합니다

xsd.exe /c MyXMLFile1.xsd 

. 클래스 이름과 속성이 현재 POCO에있는 것과 일치하지 않을 수도 있지만 은 예상 XML을 생성하고 XML에서 deserialize합니다.

추가 이점은 앞으로 XML 소스 파일을 수정 한 다음이 두 명령을 실행하여 POCO를 유지하면된다는 점입니다.

도움이 되길 ...

관련 문제