18

としてマークされたクラスと、属性DataContractでマークされたいくつかのプロパティがある場合DataMember、簡単に XML にシリアル化できますが、次のような出力が作成されます。

<Person>
    <Name>John Smith</Name>
    <Email>john.smith@acme.com</Email>
    <Phone>123-123-1234</Phone>
</Person>

私が好むのは、次のような属性です...

<Person Name="John Smith" Email="john.smith@acme.com" Phone="123-123-1234" />

属性を使用するDataMemberと、名前と順序を制御できますが、要素としてシリアル化されるか属性としてシリアル化されるかは制御できません。私は周りを見回して見つけましたが、もっと簡単な解決策があることを願っていますDataContractFormatIXmlSerializable

これを行う最も簡単な方法は何ですか?

4

3 に答える 3

39

これは、DataContractSerializer を使用して実行できます。答えは、IXmlSerializable インターフェイスを実装して、Xml シリアル化を自分で引き継ぐことです。書き込み専用のサポートの場合、ReadXml の実装を空のままにして、GetSchema に null を返し、WriteXml の実装を次のように記述できます。

public class MyPerson : IXmlSerializable
{
  public string Name { get; set;}
  public string Email { get; set;}
  public string Phone { get; set;}

  public XmlSchema GetSchema() { return null; }
  public void ReadXml(XmlReader reader) { }
  public void WriteXml(XmlWriter writer)
  { 
    writer.WriteAttributeString("name", Name);
    writer.WriteAttributeString("email", Email);
    writer.WriteAttributeString("phone", Phone);
  } 
}

たとえば、JSON シリアル化にも同じ型を使用している場合でも、DataContract および DataMember 属性を自由に追加できます。DataContractSerializer は、Xml を記述する場合にのみ IXmlSerializable インターフェイス実装を利用します。

私はこれについてここにブログを書きました。

于 2009-08-17T11:25:14.073 に答える
0

シリアル化/逆シリアル化するときに、属性と要素の間を行ったり来たりすることができます。後者の場合、以下が機能します。

    private XmlReader AttributesToElements( Stream stream )
    {
            var root = XElement.Load( stream );
            foreach ( var element in root.Descendants() ) {
                    foreach ( var attribute in element.Attributes() )
                            element.Add( new XElement( root.Name.Namespace + attribute.Name.LocalName, (string)attribute ) );
                    element.Attributes().Remove();
            }
            return root.CreateReader();
    }
于 2012-05-20T21:35:52.407 に答える