假设我有一个名为 Song 的XML可序列化类:
[Serializable]
class Song
{
public string Artist;
public string SongTitle;
}
为了节省空间(以及半混淆 XML文件),我决定重命名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>
我也想重命名/重新映射类/对象的名称。比如说,在上面的示例中,我希望将类歌曲重命名为 g 。因此,生成的xml应如下所示:
<g>
<a>Britney Spears</a>
<s>I Did It Again</s>
</g>
是否可以通过xml-attributes 重命名类名?
我不希望手动创建/遍历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()属性不会重命名列表上下文中的对象。
我错过了什么吗?
答案 0 :(得分:97)
XmlRoot仅适用于XML root 节点,根据文档(以及您所期望的,因为其名称包含 root )!< / p>
我无法得到任何其他工作的答案,所以继续挖掘...
相反,我发现 XmlTypeAttribute (即[XmlType]
)及其 TypeName 属性为非root 执行类似的工作类/对象。
e.g。
[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>
我在几个生产项目中使用过它,发现它没有任何问题。
答案 1 :(得分:51)
签出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>
答案 2 :(得分:5)
如果这是文档的根元素,您可以使用[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());
}
}
}
}
这具有生成一个表示列表本身的内部元素的副作用。在我的系统上,输出如下所示:
<?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>
答案 3 :(得分:0)
[XmlRoot("g")]
class Song
{
}
应该做的伎俩
答案 4 :(得分:0)
使用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;
}
应该有用。