0

CDATAのコレクションを含むシリアル化されたXMLを逆シリアル化したい。

XMLは次のようになります。

<User Index="1">
   <Address><![CDATA[My street 1, 1234, My city]]></Address>
   <Address><![CDATA[My next street 1, 5678, My another city]]></Address>
</User>

このように文字列として直接新しいアドレスを追加したいので:

var user = new User();
user.Addresses.Add("My street 1, 1234, My city");
user.Addresses.Add("My next street 1, 5678, My another city");

私のユーザークラスは次のようになります。

[XmlRoot("User", IsNullable = true)]
public class User
{
    [XmlIgnore]
    private XmlDocument xmlDoc;

    [XmlIgnore]
    private Collection<string> addresses;

    [XmlIgnore]
    private Collection<XmlNode> addressesNode;

    public User()
    {
        xmlDoc = new XmlDocument();
        addresses = new Collection<string>();
    }

    [XmlAttribute("Index")]
    public int Index { get; set; }

    [XmlElement("Address", IsNullable = true)]
    public Collection<XmlNode> AddressesNode
    {
        get
        {
            // This will create CDATA in address node. String values for
            // CDATA are in addresses collection.
            // This is causing problem.
            return new Collection<XmlNode>(addresses.Select(a => xmlDoc.CreateCDataSection(a)).ToArray());
        }
        set
        {
            // Set also address collection of string to the same values.
            addresses = new Collection<string>(value.Select(a => a.Value).ToArray());

            addressesNode = value;
        }
    }

    [XmlIgnore]
    public Collection<string> Addresses
    {
        get
        {
            return addresses;
        }
    }
}

これをシリアル化すると正常に機能します。ただし、逆シリアル化中に例外がスローされます

 "Collection is read-only."
4

2 に答える 2

0

ToListの代わりに電話した方がいいと思いますToArray

于 2012-08-30T14:47:55.493 に答える
0

IList をパラメーターとして渡して新しいコレクションを作成すると、元のリストのラッパーとしてコレクションが作成されます。それを新しいリストにコピーしません (こちらを参照)。addressNode セッターで、コレクションのラッパーとして新しいコレクションを作成します。List コンストラクターは元のリストをラップするのではなく、新しいリストを作成するため、代わりにこれを新しいリストに変更できます (こちらを参照)。

于 2012-08-30T14:54:58.290 に答える