web-dev-qa-db-ja.com

Serializable C#クラスでXmlArrayを使用せずにXmlArrayItem属性を使用する

次の形式のXMLが必要です。

_<configuration><!-- Only one configuration node -->
  <logging>...</logging><!-- Only one logging node -->
  <credentials>...</credentials><!-- One or more credentials nodes -->
  <credentials>...</credentials>
</configuration>
_

_[Serializable]_属性を持つクラスConfigurationを作成しようとしています。資格情報ノードをシリアル化するには、次のものがあります。

_[XmlArray("configuration")]
[XmlArrayItem("credentials", typeof(CredentialsSection))]
public List<CredentialsSection> Credentials { get; set; }
_

ただし、これをXMLにシリアル化すると、XMLは次の形式になります。

_<configuration>
  <logging>...</logging>
  <configuration><!-- Don't want credentials nodes nested in a second
                      configuration node -->
    <credentials>...</credentials>
    <credentials>...</credentials>
  </configuration>
</configuration>
_

[XmlArray("configuration")]行を削除すると、次のようになります。

_<configuration>
  <logging>...</logging>
  <Credentials><!-- Don't want credentials nodes nested in Credentials node -->
    <credentials>...</credentials>
    <credentials>...</credentials>
  </Credentials>
</configuration>
_

単一のルートノード_<credentials>_内に複数の_<configuration>_ノードを使用して、これを必要に応じてシリアル化するにはどうすればよいですか? IXmlSerializableを実装し、カスタムシリアル化を行わずにこれを実行したかったのです。これは私のクラスの説明です:

_[Serializable]
[XmlRoot("configuration")]
public class Configuration : IEquatable<Configuration>
_
47
Sarah Vessels

次のように、適切にシリアル化する必要があります。手がかりはリスト上の[XmlElement("credentials")]です。これを行うには、xmlを取得し、Visual Studioでスキーマ(xsd)を生成します。次に、スキーマでxsd.exeを実行してクラスを生成します。 (そしていくつかの小さな編集)

public class CredentialsSection
{
    public string Username { get; set; }
    public string Password { get; set; }
}

[XmlRoot(Namespace = "", IsNullable = false)]
public class configuration
{
    /// <remarks/>
    public string logging { get; set; }

    /// <remarks/>
    [XmlElement("credentials")]
    public List<CredentialsSection> credentials { get; set; }

    public string Serialize()
    {
        var credentialsSection = new CredentialsSection {Username = "a", Password = "b"};
        this.credentials = new List<CredentialsSection> {credentialsSection, credentialsSection};
        this.logging = "log this";
        XmlSerializer s = new XmlSerializer(this.GetType());
        StringBuilder sb = new StringBuilder();
        TextWriter w = new StringWriter(sb);
        s.Serialize(w, this);
        w.Flush();
        return sb.ToString();
    }
}

次の出力を与える

<?xml version="1.0" encoding="utf-16"?>
<configuration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <logging>log this</logging>
  <credentials>
    <Username>a</Username>
    <Password>b</Password>
  </credentials>
  <credentials>
    <Username>a</Username>
    <Password>b</Password>
  </credentials>
</configuration>
74
Mikael Svenson