XML序列化器在集合中的项目保持大写

7
我需要将一个以驼峰命名的项目集合导出,为此我使用了一个包装器。 这个类本身:
[XmlRoot("example")]
public class Example
{
    [XmlElement("exampleText")]
    public string ExampleText { get; set; }
}

这个可以成功序列化:

<example>
    <exampleText>Some text</exampleText>
</example>

包装器:

[XmlRoot("examples")]
public class ExampleWrapper : ICollection<Example>
{
    [XmlElement("example")]
    public List<Example> innerList;

    //Implementation of ICollection using innerList
}

这段代码会将包裹在Example中的文字转换成大写,我尝试使用XmlElement来覆盖它,但似乎没有达到预期效果。
<examples>
    <Example>
        <exampleText>Some text</exampleText>
    </Example>
    <Example>
        <exampleText>Another text</exampleText>
    </Example>
</examples>

谁能告诉我我在做什么错了或者有没有更简单的方法?

你可以将 Example 类型重命名为 example 作为一种解决方法... 如果你能忍受打破惯例的话... - RichardTowers
3个回答

5
问题在于XmlSerializer内置了对集合类型的处理,这意味着如果您的类型实现了ICollection接口,它将忽略所有属性和字段(包括innerList),并根据自己的规则进行序列化。但是,您可以使用XmlType属性自定义用于集合项的元素名称(与您在示例中使用的XmlRoot相对)。
[XmlType("example")]
public class Example
{
    [XmlElement("exampleText")]
    public string ExampleText { get; set; }
}

这将获得所需的序列化。

详见http://msdn.microsoft.com/en-us/library/ms950721.aspx,特别是回答问题“为什么不对集合类的所有属性进行序列化?”


先生,您是正确的!谢谢。我已经放弃了使用ICollection实现,转而继承List。看来XmlRoot似乎不是必需品,对吗? - siebz0r
正确的做法是,只有当你将Example作为序列化对象图的根时,才需要使用XmlRoot - luksan
这个可以工作。使用 XmlType("") 声明 DataModel 集合。 - Chathu.Thanthrige

0

很遗憾,您不能仅使用属性来实现此操作。您还需要使用属性覆盖。使用上面的类,我可以使用XmlTypeAttribute来覆盖类的字符串表示形式。

var wrapper = new ExampleWrapper();
var textes = new[] { "Hello, Curtis", "Good-bye, Curtis" };
foreach(var s in textes)
{
    wrapper.Add(new Example { ExampleText = s });
}

XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attributes = new XmlAttributes();
XmlTypeAttribute typeAttr = new XmlTypeAttribute();
typeAttr.TypeName = "example";
attributes.XmlType = typeAttr;
overrides.Add(typeof(Example), attributes);

XmlSerializer serializer = new XmlSerializer(typeof(ExampleWrapper), overrides);
using(System.IO.StringWriter writer = new System.IO.StringWriter())
{
    serializer.Serialize(writer, wrapper);
    Console.WriteLine(writer.GetStringBuilder().ToString());
}

这会给出

<examples>
  <example>
    <exampleText>Hello, Curtis</exampleText>
  </example>
  <example>
    <exampleText>Good-bye, Curtis</exampleText>
  </example>
</examples>

我相信这是你想要的。


0

[xmlType("DISPLAY_NAME")] 在集合中的 XML 序列化中用于内部对象命名。

 [XmlType("SUBSCRIPTION")]
    public class Subscription
    {

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接