【问题标题】:Generating XML from multiple classes?从多个类生成 XML?
【发布时间】:2012-03-23 12:17:15
【问题描述】:

我还有另一个关于如何让我的 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>

很抱歉打扰了,但我现在已经疯了,我确定我在这里缺少一些基本逻辑..任何人都可以给我一些关于如何以我指定的格式获取此 XML 的指示更多? 在此先感谢 Shane。

编辑:我的序列化类。

 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,显示在我的配置类之后。

           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>

【问题讨论】:

  • 你能写出你用来序列化的代码段吗?
  • 这是我的序列化代码。请注意,由于将变量移动到各自的类,因此我在写信告诉我“对象引用未设置为对象的实例”时遇到了错误。
  • @Shane'Shamus'Coulter 使用您添加到问题中的序列化代码,将使用我提供的class 修改输出您所需的 XML。要对其进行测试,您可以逐字复制我的答案中的类,填充 Config 对象并通过您发布的序列化代码运行它。您唯一需要更改的是适用的属性 getter 和 setter。
  • 我认为我在左右和居中。添加了相应的get/sets,但仍然无法以我想要的方式输出..

标签: c# .net xml


【解决方案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; }
}

这是一个控制台应用程序,它将一个对象序列化为一个文件并生成您正在寻找的确切 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
}

【讨论】:

  • 我应该将声明添加到它们各自的类中,还是将它们留在配置中?
  • @Shane'Shamus'Coulter 将它们留在您的Config 班级中。这将为您提供您在问题中提到的格式的 XML。不过,在您的问题中,您的 Config class 中有一个 List&lt;Program&gt;,但这并未在您提供的所需 XML 输出中描述。
  • 我在回答中提供的修改将为您提供您正在寻找的 XML。对于测试,您为什么不注释掉您的类,将我提供的类复制并粘贴到您的应用程序中,手动填充 Config 对象以仅用于测试并通过您的序列化代码运行它。
  • 好吧,让我试一试。虽然没有屏住呼吸:D
  • 可能真的辞掉了我的日常工作^^我正在使用你在答案中写的完全一样的类,把我的几个变量放在那里,我仍然像以前一样得到 XML。我的电子邮件设置和数据库设置根本不会在它们自己的类标签中序列化。
【解决方案2】:

我将在这里建议一种完全横向的方法,只是为了简单和维护的缘故。

如果您获取源 XML 文件并生成 XSD 架构会怎样?

例如:

xsd.exe MyXMLFile1.xml

这将生成一个 XML 架构文件 (MyXMLFile1.xsd)。获取模式并生成类(再次使用xsd.exe):

xsd.exe /c MyXMLFile1.xsd

这将生成一个有保证的可序列化 POCO,您可以继续使用它。类名和属性可能与您当前 POCO 中的不匹配,但它生成预期的 XML,并从 XML 反序列化。

额外的好处是,您只需修改源 XML 文件,然后运行这 2 个命令来维护 POCO。

希望对您有所帮助...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 2014-07-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    相关资源
    最近更新 更多