2

xml にシリアライズしたいクラスがあります。class の構造を変更せずに、生成された xml (要素内の要素) でプロパティの 1 つを下のレベルに移動したいと考えています。XmlSerializer を使用してこれを行うことは可能ですか?

例:

生成された xml:

<Person>
    <firstname xmlns=\"http://myschema.com\">John</firstname>
    <postcode xmlns=\"http://myschema.com\">N1 0XE</postcode>
</Person>

必要な xml:

<Person>
    <firstname xmlns=\"http://myschema.com\">John</firstname>
    <address>
        <postcode xmlns=\"http://myschema.com\">N1 0XE</postcode>
    </address>
</Person>

コード:

[Serializable]
[XmlType(Namespace = "http://myschema.com")]
public class Person
{
    [XmlElement("firstname")]
    public string FirstName { get; set; }

    [XmlElement("postcode")]
    public string Postcode { get; set; }
}

シリアライザー:

var xmlSerializer = new XmlSerializer(typeof(Person));
var stringWriter = new StringWriter();
var xmlWriter = XmlWriter.Create(stringWriter);

xmlSerializer.Serialize(xmlWriter, person);
4

2 に答える 2

3

生成された標準出力 xml を変更する唯一の方法は、IXmlSerializableを実装することです。したがって、共通の構造を変更する必要はありませんが、いくつかのメソッドの実装を提供する必要があります。

public class Person : IXmlSerializable
{
    [XmlElement("firstname")]
    public string FirstName { get; set; }

    [XmlElement("postcode")]
    public string Postcode { get; set; }

    #region IXmlSerializable Member

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        if (reader.Read())
        {
            FirstName = reader.ReadInnerXml();
        }

        reader.Read(); 

        Postcode = reader.ReadInnerXml();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteElementString("firstname ", FirstName);
        writer.WriteStartElement("address");
        writer.WriteElementString("postcode", Postcode);
        writer.WriteEndElement();
    }

    #endregion

    // for demo purposes only !
    public override string ToString()
    {
        return FirstName + ", " + Postcode;
    }

    // source to test the exported file and read it right after!
    Person p = new Person() { FirstName = "jon doe", Postcode = "N1 OX" };

    XmlSerializer xs = new XmlSerializer(typeof(Person));
    StreamWriter sw = new StreamWriter("export.xml");
    xs.Serialize(sw, p);
    sw.Close();

    StreamReader sr = new StreamReader("export.xml");
    Person p1 = xs.Deserialize(sr) as Person;
    Debug.WriteLine(p1.ToString());

@XmlSubElement - xmlSerialization で使用できる属性はほんの一握りです。残念ながら、 subElementや同等のものはありません

于 2012-09-04T15:23:12.763 に答える
1

クラスをまったく変更する必要がない (IXmlSerializable を実装する必要さえない) 方法が他に 2 つあります。

  1. <address>要素が書き込まれるときに要素をラップするカスタム XmlWriter 。
  2. XmlSerializer の出力を適切な XSL 変換で後処理します。
于 2012-09-04T18:19:09.987 に答える