2017-12-01 8 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; } 
} 

어떻게 든 가능합니까? 당신은 단지 직렬화해야하는 경우

+0

문제는 [KeyValuePair 목록을 XML로 serialize] (https://stackoverflow.com/a/30443169/3744182) 또는 [RestrictPar를 사용한 Xml 시퀀스 역 직렬화] (https : // stackoverflow) 문제와 매우 유사합니다. .com/a/32885108/3744182). 둘 다 'XmlSerializer'를 사용하여 쌍 요소의 시퀀스를 deserialize하는 두 가지 다른 방법을 보여주는 대답을 갖고 있습니다. 그 대답이 충분한가요, 아니면 더 많은 도움이 필요합니까? – dbc

+0

동일한 형식으로 역 직렬화 또는 다시 직렬화 만하면됩니까? – dbc

+0

직렬화 및 비 직렬화를 수행하는 [특정 순서로 C#의 병렬 배열을 XML로 직렬화] (https://stackoverflow.com/q/47641622/3744182)를 참조하십시오. – dbc

답변

1

, 당신이 그렇게 다음과 같은 유형의 XmlSerializer 사용 할 수 있습니다 : 하나의 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; } 
} 

을, 당신은 사용할 수 있습니다 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 XML 또는 Xml Sequence deserialization with RestSharp의 것과 다른 전략을 채택해야합니다.

  • http://xmltocsharp.azurewebsites.net/을 사용하여 DTO 클래스를 자동으로 생성 한 다음 내 이름 충돌에 맞게 수정했습니다.

샘플 작업 .Net fiddle.

+0

감사합니다. 이것은 올바른 방향으로 나를 잡았어. – Thomas