1

我正在用C#編寫並試圖通過IXmlSerializable類表示XML配置文件。我不能確定如何來表示我的配置文件中的嵌套元素,不過,如logLevel表示帶有IXmlSerializable類的XML配置文件

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

回答

2

創建具有單一的財產LogLevel一個子類,然後創建你的基類的日誌記錄屬性,它是新型的。

+0

我試過這樣的事情。新的'LoggingSection'類應該實現'IXmlSerializable',還是可以根據需要定義'XmlRoot'等屬性? – 2010-06-15 14:06:01

+0

這工作。我必須定義'ReadXml'和'WriteXml'來爲'LoggingSection'中的日誌級別做一些特定的事情,然後在'DLLConfigFile'中使用'Readging'和'WriteXml'來利用LoggingSection的'ReadXml'和'WriteXml'。 – 2010-06-15 14:30:43