Reputation: 2073
i have another question on getting my XML serialization neat, which i can't seem to get right. my config file is as follows:
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; }
}
}
Ideally what i want to do is have each of these three classes (email settings, database and programs) have their own tags, like so
<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>
But instead i get something that resembles this:
<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>
Sorry to be such a bother, but this is doing my nut in now and im sure there's some fundamental logic i'm missing here..can anyone give me some pointers as to how to get this XML in the format i specified above? Thanks in advance, Shane.
Edit: My serialization class.
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;
}
}
}
}
Edit 2: My new config file: @Craig - I'm using this config file, which is like you said but im still not getting the desired XML, shown after my config class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using System.Text;
namespace SMCProcessMonitor { [Serializable()]
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; }
}
}
But i am still getting:
<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>
Upvotes: 0
Views: 5581
Reputation: 7076
This will give you the desired output:
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; }
}
Here's a console application which will serialize an object to a file and produce the exact XML you are looking for. Just copy and paste it into a console application and take it from there.
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
}
Upvotes: 2
Reputation: 15794
I'm going to suggest a totally sideways approach here, just for simplicity's and maintenance's sake.
What if you took the source XML file and generated an XSD schema?
For instance:
xsd.exe MyXMLFile1.xml
This will generate an XML schema file (MyXMLFile1.xsd
). Take the schema and generate classes (again using xsd.exe
):
xsd.exe /c MyXMLFile1.xsd
This will generate a guaranteed serializable POCO that you can use going forward. The class names and properties may not match what you have in your current POCO but it will generate the expected XML, as well as deserialize from the XML.
The added benefit is that going forward, you will only have to modify the source XML file, then run these 2 commands to maintain the POCO.
Hope that helps...
Upvotes: 0