web-dev-qa-db-ja.com

List <Custom>実装のXmlArrayItem要素名を設定するにはどうすればよいですか?

次のようにカスタムXML構造を作成したいと思います。

<Hotels>
    <Hotel />
</Hotels>

これを実行できるようにするために、Listの実装を作成しました。私のコードは次のとおりです。

[XmlRootAttribute(ElementName="Hotels")]
public class HotelList: List<HotelBasic>

Listが保持するクラスの名前はHotelではなく、HotelBasicなので、私のxmlは次のようになります。

<Hotels>
   <HotelBasic />
</Hotels>

ISerializableまたはIEnumerableを実装せずにこれを修正するにはどうすればよいですか?

17
Odys

XmlSerializerを使用していると仮定して、HotelBasicクラスのシリアル化方法を変更するだけの場合は、XmlTypeAttributeを使用できます。

[XmlType(TypeName = "Hotel")]
public class HotelBasic
{
    public string Name { get; set; }
}

HotelListクラスで使用すると、次のようにシリアル化されます。

<Hotels xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Hotel>
    <Name>One</Name>
  </Hotel>
  <Hotel>
    <Name>Two</Name>
  </Hotel>
</Hotels>
17
madd0
[XmlArray("Hotels")]
[XmlArrayItem(typeof(Hotel), ElementName="Hotel")]
public HotelList[] Messages { get; set; }

生成する必要があります:

<Hotels>
    <Hotel />
    <Hotel />
</Hotels>

[XmlRoot("Hotels")]
public class HotelList : IXmlSerializable
{
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        this.Hotels = XDocument.Load(reader)
                               .Select(h => new Hotel { Name = (string)h.Attribute("name") }
                               .ToList();
    }

    public void WriteXml(XmlWriter writer)
    {
        throw new NotSupportedException();
    }
}
27
abatishchev

ここではmadd0が最も簡単なオプションを示していると思いますが、完全を期すために...個人的には「リストをルートオブジェクトとしてシリアル化する」ことはお勧めしません-さまざまな理由で(以下を含む:これらの属性が機能しないのを見たことがあります)少なくともプラットフォームでは-CFまたはSLであった可能性があり、覚えていません)。代わりに、カスタムルートタイプを使用することを常にお勧めします。

[XmlRoot("Hotels")]
public class HotelResult // or something similar
{
    [XmlElement("Hotel")]
    public List<HotelBasic> Hotels { get { return hotel; } }

    private readonly List<HotelBasic> hotels = new List<HotelBasic>();
}

これは同じxml構造を持ち、柔軟性が高くなり(ルートに他の属性/要素を追加できます)、タイプモデルにList<T>を焼き付けません(継承などよりもカプセル化を優先します)。

7
Marc Gravell