SongというXMLシリアル化可能なクラスがあるとします。
[Serializable]
class Song
{
public string Artist;
public string SongTitle;
}
スペースを節約するために(およびsemi-obfuscateXMLファイル)、xml要素の名前を変更することにしました。
[XmlRoot("g")]
class Song
{
[XmlElement("a")]
public string Artist;
[XmlElement("s")]
public string SongTitle;
}
これにより、次のようなXML出力が生成されます。
<Song>
<a>Britney Spears</a>
<s>I Did It Again</s>
</Song>
クラス/オブジェクトの名前も名前変更/再マップしたいと思います。たとえば、上記の例では、クラスの名前をSongからgに変更します。結果のXMLは次のようになります。
<g>
<a>Britney Spears</a>
<s>I Did It Again</s>
</g>
クラス名を変更することは可能ですか?via xml-attributes?
DOMを手動で作成/トラバースしたくないので、デコレータを使用してDOMを実現できるかどうか疑問に思っていました。
前もって感謝します!
更新:おっと!今回は本当にやり直しました!言及するのを忘れました-私は実際にXMLでSongオブジェクトのリストをシリアライズしています。
シリアル化コードは次のとおりです。
public static bool SaveSongs(List<Song> songs)
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Song>));
using (TextWriter textWriter = new StreamWriter("filename"))
{
serializer.Serialize(textWriter, songs);
}
}
次に、XML出力を示します。
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfSong>
<Song>
<a>Britney Spears</a>
<s>Oops! I Did It Again</s>
</Song>
<Song>
<a>Rihanna</a>
<s>A Girl Like Me</s>
</Song>
</ArrayOfSong>
どうやら、XmlRoot()属性はリストコンテキストのオブジェクトの名前を変更しません。
何か不足していますか?
XmlRoot属性をチェックアウトします。
ドキュメントはここにあります: http://msdn.Microsoft.com/en-us/library/system.xml.serialization.xmlrootattribute(v = VS.90).aspx
[XmlRoot(Namespace = "www.contoso.com",
ElementName = "MyGroupName",
DataType = "string",
IsNullable=true)]
public class Group
更新:試したところ、VS 2008で完全に動作します。このコード:
[XmlRoot(ElementName = "sgr")]
public class SongGroup
{
public SongGroup()
{
this.Songs = new List<Song>();
}
[XmlElement(ElementName = "sgs")]
public List<Song> Songs { get; set; }
}
[XmlRoot(ElementName = "g")]
public class Song
{
[XmlElement("a")]
public string Artist { get; set; }
[XmlElement("s")]
public string SongTitle { get; set; }
}
出力:
<?xml version="1.0" encoding="utf-8"?>
<sgr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www
.w3.org/2001/XMLSchema">
<sgs>
<a>A1</a>
<s>S1</s>
</sgs>
<sgs>
<a>A2</a>
<s>S2</s>
</sgs>
</sgr>
XmlRootはXMLでのみ動作しますroot nodesドキュメント(および、名前にrootが含まれる場合は予想どおり)に基づいて!
私は仕事の他の答えを得ることができなかったので、掘り続けました...
代わりに、XmlTypeAttribute(つまり、[XmlType]
)とそのTypeNameプロパティはnon-rootクラス/オブジェクトに対して同様の仕事をします。
例えば.
[XmlType(TypeName="g")]
class Song
{
public string Artist;
public string SongTitle;
}
それを他のクラスに適用すると仮定します。例えば:
[XmlType(TypeName="a")]
class Artist
{
.....
}
[XmlType(TypeName="s")]
class SongTitle
{
.....
}
これにより、以下が出力されます質問で要求されたとおり:
<g>
<a>Britney Spears</a>
<s>I Did It Again</s>
</g>
これをいくつかの生産プロジェクトで使用しましたが、問題はありませんでした。
これがドキュメントのルート要素である場合、 [XmlRoot( "g")] を使用できます。
これは、説明に基づいて更新された応答です。求めるクラスの制御は、ラッピングクラスなしでは不可能です。この例では、SongGroup
クラスを使用してリストをラップし、その中のアイテムに別名を付けることができます。
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
public class SongGroup
{
public SongGroup()
{
this.Songs = new List<Song>();
}
[XmlArrayItem("g", typeof(Song))]
public List<Song> Songs { get; set; }
}
public class Song
{
public Song()
{
}
[XmlElement("a")]
public string Artist { get; set; }
[XmlElement("s")]
public string SongTitle { get; set; }
}
internal class Test
{
private static void Main()
{
XmlSerializer serializer = new XmlSerializer(typeof(SongGroup));
SongGroup group = new SongGroup();
group.Songs.Add(new Song() { Artist = "A1", SongTitle = "S1" });
group.Songs.Add(new Song() { Artist = "A2", SongTitle = "S2" });
using (Stream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream))
{
serializer.Serialize(writer, group);
stream.Seek(0, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
}
これには、リスト自体を表すもう1つの内部要素を生成するという副作用があります。私のシステムでは、出力は次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<SongGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Songs>
<g>
<a>A1</a>
<s>S1</s>
</g>
<g>
<a>A2</a>
<s>S2</s>
</g>
</Songs>
</SongGroup>
[XmlRoot("g")]
class Song
{
}
トリックを行う必要があります
XmlElementAttributeを使用: http://msdn.Microsoft.com/en-us/library/system.xml.serialization.xmlrootattribute.aspx
[Serializable]
[XmlRoot(ElementName="g")]
class Song
{
public string Artist;
public string SongTitle;
}
動作するはずです。