representing an XML config file with an IXmlSerializable class
- by Sarah Vessels
I'm writing in C# and trying to represent an XML config file through an IXmlSerializable class. I'm unsure how to represent the nested elements in my config file, though, such as logLevel:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<logging>
<logLevel>Error</logLevel>
</logging>
<credentials>
<user>user123</user>
<host>localhost</host>
<password>pass123</password>
</credentials>
<credentials>
<user>user456</user>
<host>my.other.domain.com</host>
<password>pass456</password>
</credentials>
</configuration>
There is an enum called LogLevel that represents all the possible values for the logLevel tag. The tags within credentials should all come out as strings. In my class, called DLLConfigFile, I had the following:
[XmlElement(ElementName="logLevel", DataType="LogLevel")]
public LogLevel LogLevel;
However, this isn't going to work because <logLevel> isn't within the root node of the XML file, it's one node deeper in <logging>. How do I go about doing this?
As for the <credentials> nodes, my guess is I will need a second class, say CredentialsSection, and have a property such as the following:
[XmlElement(ElementName="credentials", DataType="CredentialsSection")]
public CredentialsSection[] AllCredentials;
Edit: okay, I tried Robert Love's suggestion and created a LoggingSection class. However, my test fails:
var xs = new XmlSerializer(typeof(DLLConfigFile));
using (var stream = new FileStream(_configPath, FileMode.Open,
FileAccess.Read, FileShare.Read))
{
using (var streamReader = new StreamReader(stream))
{
XmlReader reader = new XmlTextReader(streamReader);
var file = (DLLConfigFile)xs.Deserialize(reader);
Assert.IsNotNull(file);
LoggingSection logging = file.Logging;
Assert.IsNotNull(logging); // fails here
LogLevel logLevel = logging.LogLevel;
Assert.IsNotNull(logLevel);
Assert.AreEqual(EXPECTED_LOG_LEVEL, logLevel);
}
}
The config file I'm testing with definitely has <logging>. Here's what the classes look like:
[Serializable]
[XmlRoot("logging")]
public class LoggingSection : IXmlSerializable
{
public XmlSchema GetSchema()
{
return null;
}
[XmlElement(ElementName="logLevel", DataType="LogLevel")]
public LogLevel LogLevel;
public void ReadXml(XmlReader reader)
{
LogLevel = (LogLevel)Enum.Parse(typeof(LogLevel),
reader.ReadString());
}
public void WriteXml(XmlWriter writer)
{
writer.WriteString(Enum.GetName(typeof(LogLevel), LogLevel));
}
}
[Serializable]
[XmlRoot("configuration")]
public class DLLConfigFile : IXmlSerializable
{
[XmlElement(ElementName="logging", DataType="LoggingSection")]
public LoggingSection Logging;
}