представляет файл конфигурации XML с классом IXmlSerializable - PullRequest
1 голос
/ 15 июня 2010

Я пишу на C # и пытаюсь представить файл конфигурации XML через класс IXmlSerializable. Я не уверен, как представить вложенные элементы в моем файле конфигурации, например, такие как 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>

Существует перечисление LogLevel, которое представляет все возможные значения для тега logLevel. Все теги в пределах credentials должны быть в виде строк. В моем классе под названием DLLConfigFile у меня было следующее:

[XmlElement(ElementName="logLevel", DataType="LogLevel")]
public LogLevel LogLevel;

Однако это не сработает, поскольку <logLevel> не находится в корневом узле XML-файла, он на один узел глубже в <logging>. Как мне это сделать?

Что касается узлов <credentials>, я предполагаю, что мне понадобится второй класс, скажем, CredentialsSection, и обладающий таким свойством, как:

[XmlElement(ElementName="credentials", DataType="CredentialsSection")]
public CredentialsSection[] AllCredentials;

Редактировать: хорошо, я попробовал предложение Роберта Лава и создал класс LoggingSection. Однако мой тест не пройден:

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);
    }
}

Файл конфигурации, с которым я тестирую, определенно имеет <logging>. Вот как выглядят классы:

[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;
}

1 Ответ

2 голосов
/ 15 июня 2010

Создайте подкласс с единственным свойством LogLevel, а затем создайте в своем базовом классе свойство ведения журнала нового типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...