如何为单个属性配置多个XmlElementAttribute实现XML序列化
问题原因
XSD中的choice节点生成C#类时,Item属性的序列化逻辑由绑定的XmlElementAttribute自动匹配,无需手动指定节点名:
- 赋值
bool类型值时,自动生成<Available>节点 - 赋值字符串值时,根据格式匹配生成
<Lookup>或<Quantity>节点
你现有代码存在两处错误: - 给
Item赋值为字符串"Quantity",匹配到了<Quantity>对应的string类型规则,导致节点内容直接输出为Quantity - 序列化方法的第二个参数错误传入了
Item,应该传入你实例化的myClass对象
修复方案
直接给Item属性赋值为你需要的内容即可,序列化器会自动识别生成对应节点,修正后的代码如下:
private void myFunc() { try { var myClass = new aaaa { // 直接赋值为需要的数值字符串即可 Item = "2" }; XmlSerializer serializer = new XmlSerializer(typeof(aaaa)); // 第二个参数传入要序列化的类实例 serializer.Serialize(stringwriter, myClass); } catch (Exception ex) { // 可在此处添加异常日志逻辑 } }
同类型节点区分方案(可选)
因为<Lookup>和<Quantity>对应的类型都是string,如果遇到赋值后节点匹配错误的情况,可以通过ChoiceIdentifier明确指定节点名,修改类定义如下:
- 先定义节点类型枚举
public enum ItemChoiceType { Available, Lookup, Quantity }
- 修改
aaaa类的属性配置
public class aaaa { private object itemField; // 新增节点名指定属性,XmlIgnore避免序列化到输出中 [System.Xml.Serialization.XmlIgnore] public ItemChoiceType ItemElementName { get; set; } [System.Xml.Serialization.XmlElementAttribute("Available", typeof(bool), ChoiceIdentifier = nameof(ItemElementName))] [System.Xml.Serialization.XmlElementAttribute("Lookup", typeof(string), ChoiceIdentifier = nameof(ItemElementName))] [System.Xml.Serialization.XmlElementAttribute("Quantity", typeof(string), DataType="nonNegativeInteger", ChoiceIdentifier = nameof(ItemElementName))] public object Item { get { return this.itemField; } set { this.itemField = value; } } }
- 赋值时明确指定节点类型
var myClass = new aaaa { ItemElementName = ItemChoiceType.Quantity, Item = "2" };
该方案可以彻底避免同类型节点的匹配错误问题。
内容的提问来源于stack exchange,提问作者user3076750
相关产品推荐
相关产品推荐

