我知道他的问题已经被提出并得到了回答,但我有一种不同的情况,解决方案并没有起作用。我有一个web方法响应xsd,我需要序列化/反序列化。下面是xsd的片段,这是有问题的。
<xs:choice minOccurs="0">
<xs:element name="Type1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="string1"/>
<xs:element type="xs:string" name="string2"/>
<xs:element type="xs:boolean" name="boolean1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Type2">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:float" name="float1"/>
<xs:element type="xs:float" name="float2"/>
<xs:element type="xs:float" name="float3"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
我已经定义了这个选择元素,如下所示:
public class Type1
{
[XmlElement(IsNullable = true)]
public string string1 { get; set; }
[XmlElement(IsNullable = true)]
public string string2 { get; set; }
public bool boolean1 { get; set; }
}
public class Type2
{
public float float1 { get; set; }
public float float { get; set; }
public float float3 { get; set; }
}
[XmlElement("Type1", typeof(List<Type1>), IsNullable = true)]
[XmlElement("Type2", typeof(Type2), IsNullable = true)]
public object Type { get; set; }
问题是当我需要序列化Type1元素列表时。我明白了:
<Type1>
<Type1>
<string1>6185</string1>
<string2>VW</string2>
<boolean1>true</boolean1>
</Type1>
<Type1>
<string1>6186</string1>
<string2>AUDI</string2>
<boolean1>true</boolean1>
</Type1>
<Type1>
<string1>6187</string1>
<string2>OPEL</string2>
<boolean1>true</boolean1>
</Type1>
</Type1>
当我根据xsd,需要得到这个:
<Type1>
<string1>6185</string1>
<string2>VW</string2>
<boolean1>true</boolean1>
</Type1>
<Type1>
<string1>6186</string1>
<string2>AUDI</string2>
<boolean1>true</boolean1>
</Type1>
<Type1>
<string1>6187</string1>
<string2>OPEL</string2>
<boolean1>true</boolean1>
</Type1>
所以我的问题是,如何摆脱那个父元素&#34; Type1&#34;那封装了所有Type1列表元素?
谢谢!
答案 0 :(得分:0)
为了生成您想要的XML,您可能需要稍微更改数据模型。
XmlSerializer
支持单个多态元素或多态元素集合。在这两种情况下,它会查看每个元素的名称以确定反序列化时的实际类型。在您的情况下,您希望拥有一种类型的集合或第二种类型的单一集合。您已经通过指定XmlSerializer
有效地将集合视为类型为List<Type1>
的单例来实现此设计 - 这将需要列表的外部容器元素。
由于您不希望这样,您可以指定您的Type
属性是每种类型的多态元素的集合:
[XmlElement("Type1", typeof(Type1), IsNullable = true)]
[XmlElement("Type2", typeof(Type2), IsNullable = true)]
public List<object> Type
如果要保留当前的数据模型,可以创建一个将Type
打包到数组中的代理属性,验证该数组是包含第一个类型的集合还是第二个类型的单个集合: / p>
[XmlRoot("Root")]
public class RootObject
{
[XmlElement("Type1", typeof(Type1), IsNullable = true)]
[XmlElement("Type2", typeof(Type2), IsNullable = true)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public object [] TypeArray
{
get
{
if (Type == null)
return null;
var collection = Type as IEnumerable;
if (collection != null)
return collection.Cast<object>().ToArray();
else
return new[] { Type };
}
set
{
if (value == null)
{
Type = null;
return;
}
var type1 = value.OfType<Type1>().ToList();
var type2 = value.Where(t => t == null || t is Type2).Cast<Type2>().ToList();
if (type2.Count == 1 && type1.Count == 0)
Type = type2[0];
else if (type1.Count == value.Length)
Type = type1;
else
throw new InvalidOperationException("invalid value");
}
}
[XmlIgnore]
public object Type { get; set; }
}
原型fiddle。