使用XmlSerializer创建非标准元素

时间:2010-08-25 15:05:39

标签: c# xml xmlserializer

我正在尝试创建一个XML输出文件以导入另一个程序。我给出的示例XML文件如下所示:

    <SalesOrder>
  <OrderHeader>
    <BillTo>
      <EntityID>1234</EntityID>
    </BillTo>
  </OrderHeader>
  <LineItemList>
    <OrderLineComment>
      <LineItemID>1</LineItemID>
    </OrderLineComment>
    <LineItem>
      ...
    </LineItem>
    <LineItem>
      ...
    </LineItem>
    <LineItem>
      ...
    </LineItem>
    ...
  </LineItemList>
</SalesOrder>

我有一个C#项目,可以使用XmlSerializer输出这种类型的文件,但这部分除外:

  <LineItemList>
    <OrderLineComment>
      <LineItemID>1</LineItemID>
    </OrderLineComment>

LineItemList部分只是LineItems的列表,但是在LineItemList的开头,有一个不同的元素OrderLineComment。

如果我将其表示为LineItems数组,那么它看起来是相同的,除了它缺少OrderLineComment。如果我将此表示为包含OrderLineComment和LineItems数组的新对象LineItemList,我得到这个:

  <LineItemList>
    <OrderLineComment>
      <LineItemID>1</LineItemID>
    </OrderLineComment>
    <LineItems>
      <LineItem>
    ...
      </LineItem>
      ...
    </LineItems>

哪个有我想要的,除了它用<LineItems>标签包装所有LineItems,这不是我想要的。

所以我想知道的是:

  1. 有没有办法通过XmlSerializer来做到这一点?如果是这样,怎么样?
  2. 如果没有,我必须重写代码以使用XmlSerializer之外的其他东西,那么最好的方法是什么?为什么?
  3. 提前致谢。

2 个答案:

答案 0 :(得分:2)

您可以从公共基类派生OrderLineCommentLineItem

public abstract class LineItemBase
{
    ...
}

public class LineItem : LineItemBase
{
    ...
}

public class OrderLineComment : LineItemBase
{
    ...
}

然后将LineItemList属性声明为LineItemBase个对象的集合,并使用XmlArrayItem属性指定可以包含在集合中的类型:

[XmlArrayItem(typeof(LineItem))]
[XmlArrayItem(typeof(OrderLineComment))]
public List<LineItemBase> LineItemList { get; set; }

这应该达到你想要的效果

答案 1 :(得分:1)

您始终可以在类型上实施IXmlSerializable界面。它允许序列化任何复杂性,它适用于XmlSerializer。

修改

如果您想使用标准属性实现它,那么这是生成代码的示例。我从你的xml创建了xsd并用XSD.exe生成了代码。

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class SalesOrder {

    private OrderHeader orderHeaderField;

    private LineItemList lineItemListField;

    /// <remarks/>
    public OrderHeader OrderHeader {
        get {
            return this.orderHeaderField;
        }
        set {
            this.orderHeaderField = value;
        }
    }

    /// <remarks/>
    public LineItemList LineItemList {
        get {
            return this.lineItemListField;
        }
        set {
            this.lineItemListField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class OrderHeader {

    private BillTo billToField;

    /// <remarks/>
    public BillTo BillTo {
        get {
            return this.billToField;
        }
        set {
            this.billToField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class BillTo {

    private short entityIDField;

    /// <remarks/>
    public short EntityID {
        get {
            return this.entityIDField;
        }
        set {
            this.entityIDField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class LineItemList {

    private OrderLineComment orderLineCommentField;

    private string[] lineItemField;

    /// <remarks/>
    public OrderLineComment OrderLineComment {
        get {
            return this.orderLineCommentField;
        }
        set {
            this.orderLineCommentField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("LineItem")]
    public string[] LineItem {
        get {
            return this.lineItemField;
        }
        set {
            this.lineItemField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class OrderLineComment {

    private sbyte lineItemIDField;

    /// <remarks/>
    public sbyte LineItemID {
        get {
            return this.lineItemIDField;
        }
        set {
            this.lineItemIDField = value;
        }
    }
}