2010-08-25 2 views
0

Я пытаюсь создать выходной файл XML для импорта в другую программу. Пример XML-файл я получил выглядит так:Использование XmlSerializer для создания нестандартного элемента

<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. Если я представляю это как новый объект LineItemList, содержащий OrderLineComment и массив LineItems, я получаю это:

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

Что есть то, что я хочу, за исключением того, что оборачивает все LineItems с <LineItems> тегом, который не является что я хочу.

Так что мне интересно:

  1. Есть ли способ сделать это с помощью XmlSerializer? Если да, то как?
  2. Если этого не произошло, и я должен переписать код, чтобы использовать что-то другое, кроме XmlSerializer, что было бы лучшим способом сделать это и почему?

Заранее спасибо.

ответ

2

Вы можете сделать OrderLineComment и LineItem проистекают из общего базового класса:

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; } 

Это должно обеспечить то, что вы хотите

+0

работал как шарм - спасибо. – Whisker

1

Вы можете всегда использовать интерфейс IXmlSerializable на свой тип. Он позволяет сериализовать любую сложность и работает с XmlSerializer.

Edit:

Вот пример сгенерированного кода, если вы хотите достичь его со стандартными атрибутами. Я создал xsd из вашего xml и сгенерировал код с помощью 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; 
     } 
    } 
} 
+0

подтверждено, потому что, начав попробовать, было очевидно, что он достигнет результата, который я ищу, это просто, что решение базового класса немного быстрее и проще. Спасибо вам большое за ваш ответ. – Whisker