Reputation:
I'm trying to create an XML output file to import into another program. The example XML file I was given looks like this:
<SalesOrder>
<OrderHeader>
<BillTo>
<EntityID>1234</EntityID>
</BillTo>
</OrderHeader>
<LineItemList>
<OrderLineComment>
<LineItemID>1</LineItemID>
</OrderLineComment>
<LineItem>
...
</LineItem>
<LineItem>
...
</LineItem>
<LineItem>
...
</LineItem>
...
</LineItemList>
</SalesOrder>
I have a C# project that is able to output this type of file using an XmlSerializer with the exception of this part:
<LineItemList>
<OrderLineComment>
<LineItemID>1</LineItemID>
</OrderLineComment>
The LineItemList section is simply a list of LineItems, but at the beginning of the LineItemList there is tacked this different element OrderLineComment.
If I represent this as an array of LineItems, then it looks the same except it's missing the OrderLineComment. If I represent this as a new object LineItemList containing an OrderLineComment and an array of LineItems, I get this:
<LineItemList>
<OrderLineComment>
<LineItemID>1</LineItemID>
</OrderLineComment>
<LineItems>
<LineItem>
...
</LineItem>
...
</LineItems>
Which has what I want, except it wraps all the LineItems with the <LineItems>
tag, which isn't what I want either.
So what I'm wondering is:
Thanks in advance.
Upvotes: 0
Views: 186
Reputation: 292555
You can make a OrderLineComment
and LineItem
derive from a common base class :
public abstract class LineItemBase
{
...
}
public class LineItem : LineItemBase
{
...
}
public class OrderLineComment : LineItemBase
{
...
}
Then declare the LineItemList
property as a collection of LineItemBase
objects, and use the XmlArrayItem
attribute to specify which types can be included in the collection:
[XmlArrayItem(typeof(LineItem))]
[XmlArrayItem(typeof(OrderLineComment))]
public List<LineItemBase> LineItemList { get; set; }
This should achieve what you want
Upvotes: 2
Reputation: 364359
You can always implement IXmlSerializable interface on your type. It allows serialization of any complexity and it works with XmlSerializer.
Edit:
Here is the example of generated code if you want to achieve it with standard attributes. I created xsd from your xml and generated the code with 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;
}
}
}
Upvotes: 1