6

C#/.NET を使用して、次のような XML ファイルを逆シリアル化しています。

<?xml version="1.0" encoding="utf-8" ?>
<Books>
  <Book
    Title="Animal Farm"
    >
    <Thing1>""</Thing1>
    <Thing2>""</Thing2>
    <Thing3>""</Thing3>
    ...
    <ThingN>""</ThingN>
  </Book>
  ... More Book nodes ...
</Books>

デシリアライズされた XML の私のクラスは次のようになります。

[XmlRoot("Books")]
public class BookList
{
    // Other code removed for compactness. 

    [XmlElement("Book")]
    public List<Book> Books { get; set; }
}

public class Book
{
    // Other code removed for compactness. 

    [XmlAttribute("Title")]
    public string Title { get; set; }

    [XmlAnyElement()]
    public List<XmlElement> ThingElements { get; set; }

    public List<Thing> Things { get; set; }
}  

public class Thing
{
    public string Name { get; set; }
    public string Value { get; set; }
} 

逆シリアル化するとき、Book 要素 (<Thing1> から <ThingN> まで) のすべての子ノードを、Book の Things コレクションに逆シリアル化する必要があります。ただし、それを達成する方法がわかりません。現在、モノのノードを ThingElements コレクションに (XmlAnyElement 経由で) 格納するのに苦労しています。

異種の子ノードを (非 XmlElements の) コレクションに逆シリアル化する方法はありますか?

4

2 に答える 2

2

これを単純な KeyValuePairs のセットとしてシリアル化したい場合は、カスタム Struct を使用してこれを実現できます。残念ながら、組み込みの汎用 KeyValuePair は機能しません。

ただし、次のクラス定義が与えられた場合:

[XmlRoot("Books")]
public class BookList
{
    [XmlElement("Book")]
    public List<Book> Books { get; set; }
}

public class Book
{
    [XmlAttribute("Title")]
    public string Title { get; set; }

    [XmlElement("Attribute")]
    public List<AttributePair<String, String>> Attributes { get; set; }
}

[Serializable]
[XmlType(TypeName = "Attribute")]
public struct AttributePair<K, V>
{
    public K Key { get; set; }
    public V Value { get; set; }

    public AttributePair(K key, V val)
        : this()
    {
        Key = key;
        Value = val;
    }
}

この情報を使用してオブジェクトをシリアル化すると、次のような XML 構造が得られます。

<?xml version="1.0"?>
<Books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Book Title="To win a woman">
    <Attribute>
      <Key>Author</Key>
      <Value>Bob</Value>
    </Attribute>
    <Attribute>
      <Key>Publish Date</Key>
      <Value>1934</Value>
    </Attribute>
    <Attribute>
      <Key>Genre</Key>
      <Value>Romance</Value>
    </Attribute>
  </Book>
</Books>

また、その XML をオブジェクトに正しく読み込んで、情報を出力することもできました。

コンソール アプリケーションでテストして、結果を確認できます。

using(var file = File.OpenRead("booklist.xml"))
{
    var readBookCollection = (BookList)serializer.Deserialize(file);

    foreach (var book in readBookCollection.Books)
    {
        Console.WriteLine("Title: {0}", book.Title);

        foreach (var attributePair in book.Attributes)
        {
            Console.CursorLeft = 3;
            Console.WriteLine("Key: {0}, Value: {1}", 
                attributePair.Key, 
                attributePair.Value);
        }
    }
}
于 2013-11-11T03:21:56.980 に答える