当 [XmlElement] 和 [XmlText] 结合使用时的 XML 序列化差异






4.78/5 (4投票s)
本技巧展示了当可序列化类同时具有 [XmlElement] 和 [XmlText] 时,XML 序列化的差异。
引言
本技巧展示了当可序列化类同时具有 [XmlElement]
和 [XmlText]
时,XML 序列化的差异。
背景
XML 序列化可以通过各种方式和技术实现。 在本技巧中,我想展示我在使用声明为 [XmlElement]
的集合和声明为 [XmlText]
的 string
的可序列化类时遇到的差异。
Using the Code
可序列化类
该类具有以下属性
- 一个
string
作为属性 -[XmlAttribute]
- 一个
string
作为文本属性 -[XmlText]
- 一个
集合
作为元素 -[XmlElement]
[XmlType(AnonymousType = true)]
public class Person
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlText]
public string Text { get; set; }
[XmlElement("person")]
public Collection<Person> Children { get; set; }
public bool ShouldSerializeChildren()
{
return Children != null && Children.Count > 0;
}
public string Serialize()
{
var sw = new StringWriter();
var serializer = new XmlSerializer(typeof(Person));
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
serializer.Serialize(sw, this, ns);
return sw.ToString();
}
}
在未分配文本属性的情况下序列化类
仅分配 name
属性和 collection
元素。
var person = new Person
{
Name = "name",
Children =
new Collection<Person>
{
new Person {Name = "child1", Text = "child1Text"},
new Person {Name = "child2", Text = "child2Text"}
}
};
var personWithoutText = person.Serialize();
Console.WriteLine("Person without text attribute has new lines:");
Console.WriteLine("-------------------------------------------");
Console.WriteLine(personWithoutText);
Console.WriteLine();
结果
结果将是一个带有集合项之间换行的漂亮缩进的 XML。
<?xml version="1.0" encoding="utf-16"?>
<Person name="name">
<person name="child1">child1Text</person>
<person name="child2">child2Text</person>
</Person>
分配文本属性后序列化类
person.Text = "text";
var personWithTextAttribue = person.Serialize();
Console.WriteLine("Person with text attribute has no new lines:");
Console.WriteLine("-------------------------------------------");
Console.WriteLine(personWithTextAttribue);
Console.ReadLine();
结果
结果将是一个没有集合项之间换行的 XML。
<?xml version="1.0" encoding="utf-16"?>
<Person name="name">text<person name="child1">child1Text</person>
<person name="child2">child2Text</person></Person>
结论
我找到的解决方法是,确保可序列化类中没有文本属性。
关注点
为什么我将集合属性声明为 XmlElement
?
如果集合未声明为 XmlElement
,则其项将编码为以属性名称命名的元素下嵌套的元素序列。(请参阅 MSDN 中的 XmlElementAttribute)
类似这样的东西
<myserializableclass>
<wrappingelement>
<item>item1</item>
<item>item2</item>
<item>item3</item>
<myserializableclass>
</myserializableclass>
为了避免元素包装集合的项,我将集合声明为 [XmlElement]
。
序列化结果将是
<MySerializableClass>
<item>item1</item>
<item>item2</item>
<item>item3</item>
</MySerializableClass>
历史
- 2015 年 2 月 14 日:初始版本
- 2015 年 2 月 17 日:编辑结论并更新代码(修复了命名空间和 XML 属性)