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

inv*_*ass 63 c# xml xml-serialization

假设我有一个名为Song的XML可序列化类:

[Serializable]
class Song
{
    public string Artist;
    public string SongTitle;
}
Run Code Online (Sandbox Code Playgroud)

为了节省空间(并且还对XML文件进行半混淆),我决定重命名xml元素:

[XmlRoot("g")]
class Song
{
    [XmlElement("a")]
    public string Artist;
    [XmlElement("s")]
    public string SongTitle;
}
Run Code Online (Sandbox Code Playgroud)

这将生成如下的XML输出:

<Song>
  <a>Britney Spears</a>
  <s>I Did It Again</s>
</Song>
Run Code Online (Sandbox Code Playgroud)

我想重命名/重新映射类/对象的名称.比如,在上面的例子中,我希望将类Song重命名为g.因此,生成的xml应如下所示:

<g>
  <a>Britney Spears</a>
  <s>I Did It Again</s>
</g>
Run Code Online (Sandbox Code Playgroud)

是否可以通过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);
            }
    }
Run Code Online (Sandbox Code Playgroud)

这是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>
Run Code Online (Sandbox Code Playgroud)

显然,XmlRoot()属性不会重命名列表上下文中的对象.

我错过了什么吗?

Gon*_*ing 104

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

XmlRoot只能使用XML的节点按照文档(和你所期望的,它的名字包括)!

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

相反,我发现XmlTypeAttribute(ie [XmlType])及其TypeName属性为非根类/对象执行类似的工作.

例如

[XmlType(TypeName="g")]
class Song
{
    public string Artist;
    public string SongTitle;
}
Run Code Online (Sandbox Code Playgroud)

假设您将其应用于其他类,例如:

[XmlType(TypeName="a")]
class Artist
{
    .....
}

[XmlType(TypeName="s")]
class SongTitle
{
    .....
}
Run Code Online (Sandbox Code Playgroud)

这将完全按照问题的要求输出以下内容:

<g>
  <a>Britney Spears</a>
  <s>I Did It Again</s>
</g>
Run Code Online (Sandbox Code Playgroud)

我在几个生产项目中使用过它,发现它没有任何问题.

  • 这个答案比选择的答案好很多. (4认同)

Ari*_*sky 57

签出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
Run Code Online (Sandbox Code Playgroud)

更新:刚试过,它在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; }
} 
Run Code Online (Sandbox Code Playgroud)

输出:

<?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>
Run Code Online (Sandbox Code Playgroud)

  • @Arial:有同样的问题,但发现XmlRoot属性只适用于我的根节点(因为我猜它应该基于文档).不确定如何使上述代码正常工作.让它在我的类上使用[XmlType(TypeName ="newName")]. (14认同)
  • `XmlArrayItem("g")`就是我想要的 (3认同)
  • 输出不正确你松开<g> ... </ g>,但这不能解决问题.解决方案是"HiTech Magic"的帖子[XmlType(TypeName ="g")] (2认同)

bob*_*mcr 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());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这具有生成表示列表本身的一个或多个内部元素的副作用.在我的系统上,输出如下所示:

<?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>
Run Code Online (Sandbox Code Playgroud)