2017-12-01 11 views
0

「DUE」と「RATE」をXmlSerializerでオブジェクトのリストにマップする必要がある次のXMLがあります。 0から多くのものがあり得ますが、それらは常に同じ "idx"とペアになります。リストに同じ名前のXML値

<INVOICE ID="4"> 
    <STATUS>S</STATUS> 
    <TOTAL>6230.00</TOTAL> 
    <DUE idx="1">14.12.17</DUE> 
    <RATE idx="1">6230.00</RATE> 
</INVOICE > 
<INVOICE ID="5"> 
    <STATUS>S</STATUS> 
    <TOTAL>3270.00</TOTAL> 
    <DUE idx="1">30.11.17</DUE> 
    <RATE idx="1">1090.00</RATE> 
    <DUE idx="2">07.12.17</DUE> 
    <RATE idx="2">1090.00</RATE> 
    <DUE idx="3">14.12.17</DUE> 
    <RATE idx="3">1090.00</RATE> 
</INVOICE> 

私は「レート」と「原因」のリストなしで正常に動作している以下の設定があります。

[Serializable] 
public class UserInvoicesDto 
{ 
    [XmlElement("INVOICE")] 
    public List<UserInvoiceDto> Invoices { get; set; } 
} 

[Serializable, XmlRoot("INVOICE")] 
public class UserInvoiceDto 
{ 
    [XmlAttribute("id")] 
    public int InvoiceId { get; set; } 
    [XmlElement("TOTAL")] 
    public string Total { get; set; } 
} 

をそして私は、以下のクラスを持っています。

[Serializable] 
public class InvoicesDueDates 
{ 
    [XmlAttribute("idx")] 
    public string Id { get; set; } 
    [XmlElement("DUE")] 
    public string DueDate { get; set; } 
    [XmlElement("RATE")] 
    public string Rate { get; set; } 
} 

どういうことですか?あなたが使用することができ、単一InvoicesDueDatesコレクションにRateDueリストを組み合わせることが、その後

[XmlRoot(ElementName = "DUE")] 
public class DueDTO 
{ 
    [XmlAttribute(AttributeName = "idx")] 
    public string Idx { get; set; } 
    [XmlText] 
    public string Text { get; set; } 
} 

[XmlRoot(ElementName = "RATE")] 
public class RateDTO 
{ 
    [XmlAttribute(AttributeName = "idx")] 
    public string Idx { get; set; } 
    [XmlText] 
    public decimal Text { get; set; } 
} 

[XmlRoot(ElementName = "INVOICE")] 
public partial class InvoicesDTO 
{ 
    [XmlAttribute(AttributeName = "ID")] 
    public string Id { get; set; } 
    [XmlElement(ElementName = "STATUS")] 
    public string Status { get; set; } 
    [XmlElement(ElementName = "TOTAL")] 
    public decimal Total { get; set; } 

    [XmlElement(ElementName = "DUE")] 
    public List<DueDTO> Due { get; set; } 
    [XmlElement(ElementName = "RATE")] 
    public List<RateDTO> Rate { get; set; } 
} 

:あなたが唯一のデシリアライズに必要がある場合は

+0

問題は[KeyValuePairのリストをXMLにシリアライズする](https://stackoverflow.com/a/30443169/3744182)または[Restart with Restricted Xml Sequence deserialization](https:// stackoverflow)の問題と非常によく似ています.com/a/32885108/3744182)。両方とも、 'XmlSerializer'を使用して、ペア要素のシーケンスを逆シリアル化する2つの異なる方法を示す回答があります。それらの答えは十分ですか、それとももっと助けが必要ですか? – dbc

+0

デシリアライズするだけで済みますか、同じフォーマットで再シリアライズする必要はありますか? – dbc

+0

シリアライゼーションとデシリアライズを行う[特定の順序でC#でXMLにパラレルアレイをシリアル化する](https://stackoverflow.com/q/47641622/3744182)も参照してください。 – dbc

答えて

1

、あなたは次のタイプにXmlSerializerを使用して、そう使用することができますLINQ、例えば次のように:

public partial class InvoicesDTO 
{ 
    public InvoicesDueDates[] InvoicesDueDates 
    { 
     get 
     { 
      // To make suure we handle cases where only a Rate or Due item of a specific index is present, 
      // perform left outer joins with all indices on both Rate and Due. 
      // https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-left-outer-joins 
      var query = from i in Due.Select(d => d.Idx).Concat(Rate.Select(r => r.Idx)).Distinct() 
         join due in Due on i equals due.Idx into dueGroup 
         // Throw an exception if we have more than one due item for a given index 
         let due = dueGroup.SingleOrDefault() 
         join rate in Rate on i equals rate.Idx into rateGroup 
         // Throw an exception if we have more than one rate item for a given index 
         let rate = rateGroup.SingleOrDefault() 
         select new InvoicesDueDates { Id = i, DueDate = due == null ? null : due.Text, Rate = rate == null ? (decimal?)null : rate.Text }; 
      return query.ToArray(); 
     } 
    } 
} 

public class InvoicesDueDates 
{ 
    public string Id { get; set; } 
    public string DueDate { get; set; } 
    public decimal? Rate { get; set; } 
} 

注:

  • このソリューションは、XmlSerializerは、他の要素と交互にList<T>財産との出会いリスト要素をデシリアライズされたとき、それはそれぞれを追加します、という事実を利用します成長するリストに遭遇したリスト要素。すべての情報が保持され、再シリアル化されてい

    <INVOICE ID="5"> 
        <STATUS>S</STATUS> 
        <TOTAL>3270.00</TOTAL> 
        <DUE idx="1">30.11.17</DUE> 
        <DUE idx="2">07.12.17</DUE> 
        <DUE idx="3">14.12.17</DUE> 
        <RATE idx="1">1090.00</RATE> 
        <RATE idx="2">1090.00</RATE> 
        <RATE idx="3">1090.00</RATE> 
        </INVOICE> 
    

    お知らせけど<RATE><DUE>シーケンスが分離されています:あなたがいる場合

  • は、結果は次のようになりますInvoicesDTO再シリアライズ。あなたは、インターリーブ<RATE><DUE>要素で再シリアライズする必要がある場合は

  • 、あなたは、このようなserializing a list of KeyValuePair to XMLXml Sequence deserialization with RestSharpからのものと異なる戦略を採用する必要があります。

  • http://xmltocsharp.azurewebsites.net/を使用してDTOクラスを自動生成し、私の命名の競合に合わせて修正しました。

サンプル作業.Net fiddle

+0

ありがとう。これは正しい方向に私を得た。 – Thomas

関連する問題