在可序列化的 C# 类上使用没有 XmlArray 的 XmlArrayItem 属性

Posted

技术标签:

【中文标题】在可序列化的 C# 类上使用没有 XmlArray 的 XmlArrayItem 属性【英文标题】:using XmlArrayItem attribute without XmlArray on Serializable C# class 【发布时间】:2011-03-19 04:55:49 【问题描述】:

我想要以下格式的 XML:

<configuration><!-- Only one configuration node -->
  <logging>...</logging><!-- Only one logging node -->
  <credentials>...</credentials><!-- One or more credentials nodes -->
  <credentials>...</credentials>
</configuration>

我正在尝试创建一个具有[Serializable] 属性的类Configuration。要序列化凭据节点,我有以下内容:

[XmlArray("configuration")]
[XmlArrayItem("credentials", typeof(CredentialsSection))]
public List<CredentialsSection> Credentials  get; set; 

但是,当我将其序列化为 XML 时,XML 的格式如下:

<configuration>
  <logging>...</logging>
  <configuration><!-- Don't want credentials nodes nested in a second
                      configuration node -->
    <credentials>...</credentials>
    <credentials>...</credentials>
  </configuration>
</configuration>

如果我删除 [XmlArray("configuration")] 行,我会得到以下信息:

<configuration>
  <logging>...</logging>
  <Credentials><!-- Don't want credentials nodes nested in Credentials node -->
    <credentials>...</credentials>
    <credentials>...</credentials>
  </Credentials>
</configuration>

如何以我想要的方式序列化这个,在单个根节点 &lt;configuration&gt; 中有多个 &lt;credentials&gt; 节点?我想这样做而不必实现IXmlSerializable 并进行自定义序列化。这就是我的班级的描述方式:

[Serializable]
[XmlRoot("configuration")]
public class Configuration : IEquatable<Configuration>

【问题讨论】:

【参考方案1】:

以下内容应该按照您想要的方式正确序列化。线索是列表中的[XmlElement("credentials")]。我通过获取您的 xml,在 Visual Studio 中从中生成架构 (xsd) 来做到这一点。然后在架构上运行 xsd.exe 以生成一个类。 (以及一些小的修改)

public class CredentialsSection

    public string Username  get; set; 
    public string Password  get; set; 


[XmlRoot(Namespace = "", IsNullable = false)]
public class configuration

    /// <remarks/>
    public string logging  get; set; 

    /// <remarks/>
    [XmlElement("credentials")]
    public List<CredentialsSection> credentials  get; set; 

    public string Serialize()
    
        var credentialsSection = new CredentialsSection Username = "a", Password = "b";
        this.credentials = new List<CredentialsSection> credentialsSection, credentialsSection;
        this.logging = "log this";
        XmlSerializer s = new XmlSerializer(this.GetType());
        StringBuilder sb = new StringBuilder();
        TextWriter w = new StringWriter(sb);
        s.Serialize(w, this);
        w.Flush();
        return sb.ToString();
    

给出以下输出

<?xml version="1.0" encoding="utf-16"?>
<configuration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <logging>log this</logging>
  <credentials>
    <Username>a</Username>
    <Password>b</Password>
  </credentials>
  <credentials>
    <Username>a</Username>
    <Password>b</Password>
  </credentials>
</configuration>

【讨论】:

是的,成功了!我是如此确定“这是一个List,必须在某处使用XmlArrayItem 属性”,以至于我什至没有想过将其设为常规XmlElement 好答案,我有同样的问题 - 我想删除: 解决了它: [XmlElement("DATAITEM")] public列表 数据项 获取;放; 谢谢米凯尔。这帮助我解决了今天的问题。 +1 它仅在使用 XmlSerializer 时有效。在 WCF DataContract 中,在 WCF DataMember 中使用时,它不起作用,例如 [XmlElement("credentials")] [DataMember] public List&lt;CredentialsSection&gt; credentials get; set; 。似乎 WCF 忽略了用于序列化的 Xml* 属性。有什么建议吗? 非常感谢!那把我所有的 XmlArray , XmlArrayItem, ... 答案都给杀了。

以上是关于在可序列化的 C# 类上使用没有 XmlArray 的 XmlArrayItem 属性的主要内容,如果未能解决你的问题,请参考以下文章

在可移动和不可复制的类上使用移动和交换习语是不是有意义

将 C# 列表序列化为具有内部数组的复数命名对象

对象序列和反序列化Xml

在可序列化之后使用 onBackPressed() 发回列表

C#与Java在继承静态类上的区别

使用 iText 7 和 C# 在可访问的 pdf 中将标题添加为 H1