web-dev-qa-db-ja.com

DataContract XMLシリアル化とXML属性

このXMLをDataContract属性でマークされたオブジェクトにデシリアライズすることは可能ですか?

<root>
<distance units="m">1000</distance>
</root>

ご覧のとおり、「ユニット」属性があります。それがサポートされているとは思わない。それとも私は間違っていますか?

41
Schultz9999

これは実現できますが、[XmlSerializerFormat]属性をDataContractに適用することにより、デフォルトのシリアライザーをオーバーライドする必要があります。実行はできますが、これはデフォルトのシリアライザほど性能がよくないため、注意して使用してください。

次のクラス構造により、目的の結果が得られます。

using ...
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Xml.Serialization;

[DataContract]
[XmlSerializerFormat]
public class root
{
   public distance distance=new distance();
}

[DataContract]
public class distance
{
  [DataMember, XmlAttribute]
  public string units="m";

  [DataMember, XmlText]
  public int value=1000;
}

次のコードでこれをテストできます。

root mc = new root();
XmlSerializer ser = new XmlSerializer(typeof(root));
StringWriter sw = new StringWriter();
ser.Serialize(sw, mc);
Console.WriteLine(sw.ToString());
Console.ReadKey();

出力は次のようになります。

<?xml version="1.0" encoding="utf-16"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <distance units="m">1000</distance>
</root>
53
Greg Sansom

WCFで既定で使用されるデータコントラクトシリアライザーは、パフォーマンス上の理由でnotXML属性をサポートします(DCSはXMLシリアライザーよりも平均で約10%高速です) 。

したがって、DCSを本当に使用したい場合、この構造を使用することはできません。変更する必要があります。

または、グレッグが答えで示したように、WCFでXmlSerializerを使用する必要があります-これも機能しますが、DCSのパフォーマンス上の利点(およびその他のすべての利点)を失います。

26
marc_s