如何序列化列表< T> c#中的属性,但未在XML序列化中显示其类型
我有一个需要以XML序列化的类.下面是示例:
I have a class for which I need to serialize it in XML. Below is the example:
public class StringArray
{
public List<string> Days { get; set; }
public StringArray()
{
List<string> s = new List<string>();
s.Add("Monday");
s.Add("Tuesday");
s.Add("Wed");
Days = s;
}
}
当我以XML格式序列化它时,结果是:
When I Serialize it in XML format then result is:
<StringArray xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Days>
<string>Monday</string>
<string>Tuesday</string>
<string>Wed</string>
</Days>
</StringArray>
但是,我需要如下所示的结果:
However, I need result like below:
<StringArray xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Days>
<Monday />
<Tuesday />
<Wed />
</Days>
</StringArray>
实际上我不想显示列表项的类型.
Actually I do not want to show the type of list item.
请注意,可能的字符串集是固定的.我也尝试为此使用enum
,但是XML显示的是enum
类型名称而不是'string',这不能解决问题.
Note that the set of possible strings is fixed. I also tried using an enum
for this, however the XML shows the enum
type name instead of 'string' which doesn't solve the problem.
由于只有固定的一组可能的字符串值,因此您的架构对应于无限制的选择元素,其中可能的元素名称与可能的字符串值相对应.
Since you have only a fixed set of possible string values, your schema corresponds to an unbounded sequence of choice elements, where the possible element names correspond to the possible string values.
这可以通过以下方式建模:将string
替换为适当的enum
,然后使用选择元素绑定支持支持内置在
This can be modeled by replacing the string
with some appropriate enum
, then making use of the Choice Element Binding Support support built in to XmlSerializer
, which requires application of XmlChoiceIdentifierAttribute
along with the use of an appropriate serialization surrogate DTO.
首先,定义一个与可能的字符串值相对应的enum
:
First, define an enum
that corresponds to the possible string values:
public enum Day
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
接下来,定义以下DTO,这些DTO将取代您的List<Day>
:
Next, define the following DTO which will be serialized in place of your List<Day>
:
public class DayListDTO
{
[XmlIgnore]
public Day [] Days { get; set; }
[XmlChoiceIdentifier(nameof(DayListDTO.Days))]
[XmlElement(nameof(Day.Monday), typeof(object))]
[XmlElement(nameof(Day.Tuesday), typeof(object))]
[XmlElement(nameof(Day.Wednesday), typeof(object))]
[XmlElement(nameof(Day.Thursday), typeof(object))]
[XmlElement(nameof(Day.Friday), typeof(object))]
[XmlElement(nameof(Day.Saturday), typeof(object))]
[XmlElement(nameof(Day.Sunday), typeof(object))]
public object[] DaysObjects
{
get
{
return Days == null ? null : Enumerable.Repeat(new object(), Days.Length).ToArray();
}
set
{
// Do nothing
}
}
public static implicit operator DayListDTO(List<Day> list)
{
return list == null ? null : new DayListDTO { Days = list.ToArray() };
}
public static implicit operator List<Day>(DayListDTO dayList)
{
return dayList?.Days?.ToList() ?? new List<Day>();
}
}
最后,通过将代理属性添加到包含类中来利用DTO,如下所示:
Finally, make use of the DTO by adding surrogate properties to containing classes as follows:
public class StringArray
{
[XmlIgnore]
public List<Day> Days { get; set; }
[XmlElement("Days")]
public DayListDTO XmlDaysSurrogate { get { return Days; } set { Days = value; } }
}
序列化后会生成以下XML:
Which, when serialized, generates the following XML:
<StringArray xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Days>
<Monday />
<Tuesday />
<Wednesday />
</Days>
</StringArray>
注意:
-
要在数组上正确使用
XmlChoiceIdentifier
,包含的DTO类型必须具有两个数组成员:
To use
XmlChoiceIdentifier
correctly with an array, your containing DTO type must have two array members:
- 一个数组,记录选择元素的内容,此处为
DayListDTO.DaysObjects
; - 一个数组,该数组记录选择元素的名称(此处为
DayListDTO.Days
),与第一个数组成1-1对应.
- One array that records the contents of the choice elements, here
DayListDTO.DaysObjects
; - One array that records the names of the choice elements, here
DayListDTO.Days
, in 1-1 correspondence with the first array.
由于与您的枚举列表相对应的元素根本不包含任何内容,因此将为第一个数组返回object
个项目的虚拟数组.
使用XmlChoiceIdentifier
保证 xsd.exe
会正确地指示正确命名的选择元素的无限范围.其他解决方案(例如,通过 IXmlSerializable
在List<Day>
的某些子类上实现自定义序列化)没有这种优势.
Using XmlChoiceIdentifier
guarantees that the schema which xsd.exe
auto-generates for your types will correctly indicate an unbounded sequence of correctly-named choice elements. Other solutions such as implementing custom serialization via IXmlSerializable
on some subclass of List<Day>
do not have this advantage.
工作示例小提琴此处.