如何通过 XML 属性重命名类名?

假设我有一个名为 的 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>

我还想重命名/重映射类/对象的名称。例如,在上面的示例中,我希望将类 重命名为 。因此,生成的 xml 应该如下所示:

<g>
<a>Britney Spears</a>
<s>I Did It Again</s>
</g>

可以重命名类名 通过 xml 属性吗?

我不希望手动创建/遍历 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 ()属性不会在列表上下文中重命名对象。

我错过了什么吗?

84366 次浏览

签出 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 (“ 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>
[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;
}

应该可以。

解决方案: 使用[ XmlType (TypeName = “ g”)]

根据文档,XmlRoot 只与 XML 节点 一起工作(考虑到它的名称包括 ,您可能会有所期望) !

我无法得到任何其他的答案,所以继续挖掘..。

相反,我发现 XmlTypeAttribute(即 [XmlType])及其 类型名称属性对 非根类/对象做了类似的工作。

例如:。

[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>

我已经在几个生产项目中使用了它,并且没有发现任何问题。