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

时间:2010-09-06 17:59:45

标签: c# xml xml-serialization

假设我有一个名为 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()属性不会重命名列表上下文中的对象。

我错过了什么吗?

5 个答案:

答案 0 :(得分:97)

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

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;
}

应该有用。