2013-04-22 133 views
1

我有以下类结构我想序列化到XML:冗余元素序列化类时为XML叶元素属性

public class Foo 
{ 
    [XmlArray("approxPriceList")] 
    [XmlArrayItem("approxPrice")] 
    public List<ApproxPriceElement> ApproxPriceList { get; set; } 
} 

public class ApproxPriceElement 
{ 
    [XmlAttribute("currency")] 
    public string Currency { get; set; } 

    [XmlElement("approxPrice")] 
    public decimal? ApproxPrice { get; set; } 
} 

如果我序列Foo,我得到以下XML:

<approxPriceList> 
    <approxPrice currency="aud"> 
     <approxPrice>2220.00</approxPrice> 
    </approxPrice> 
</approxPriceList> 

我想是这样的:

<approxPriceList> 
    <approxPrice currency="aud">2220.00</approxPrice> 
</approxPriceList> 

唯一的想法是将Foo中的ApproxPriceList更改为List<decimal?>,但我无法弄清楚如何将currency属性与列表中的每个approxPrice关联起来。

有没有办法做到这一点?

回答

1

使用XmlText,而不是XmlElement("approxPrice")

[XmlText] 
public decimal? ApproxPrice { get; set; } 

为了使该元件是null补充一点:

[XmlArrayItem("approxPrice", IsNullable = true)] 
public List<ApproxPriceElement> ApproxPriceList { get; set; } 

这里有一个建议的解决办法,为“不能用于编码复杂类型“异常(source):

[XmlText] 
    public decimal ApproxPrice { get; set; } 
    [XmlIgnore] 
    public bool ApproxPriceSpecified { get { return ApproxPrice >= 0; } } 
+0

这似乎只在我使用非空值时才起作用,即'decimal'而不是'decimal?'。否则,当我序列化时,我得到一个异常,表明'XmlText'不能用于复杂类型。 – LeopardSkinPillBoxHat 2013-04-22 01:07:20

+0

@LeopardSkinPillBoxHat我已经更新了答案,检查它是否修复了问题 – nmat 2013-04-22 01:16:38

+0

不,我得到了同样的错误“Can not serialize member'ApproxPrice'of System.Nullable'1 [System.Decimal]。XmlAttribute/XmlText无法使用编码复杂类型“。 我想我有一个解决方法:(1)将属性更改为不可为空; (2)将'ShouldSerializeApproxPrice'方法添加到'ApproxPrice'属性,如果该属性设置为特殊值(例如-1)则返回false。 – LeopardSkinPillBoxHat 2013-04-22 01:40:47

0

你可以使用IXmlSerializable

public class Foo : IXmlSerializable 
    { 
     public Foo() 
     { 
      ApproxPriceList = new List<ApproxPriceElement>(); 
     } 

     public List<ApproxPriceElement> ApproxPriceList { get; set; } 

     public XmlSchema GetSchema() 
     { 
      return null; 
     } 

     public void ReadXml(XmlReader reader) 
     { 
      while (reader.Read()) 
      { 
       if (reader.IsStartElement()) 
       { 
        switch (reader.LocalName) 
        { 
         case "approxPrice": 
          { 
           var approxPrice = new ApproxPriceElement(); 

           approxPrice.Currency = reader.GetAttribute("currency"); 

           var approxPriceValue = reader.ReadElementContentAsString(); 

           if (!string.IsNullOrEmpty(approxPriceValue)) 
           { 
            approxPrice.ApproxPrice = decimal.Parse(approxPriceValue); 
           } 

           ApproxPriceList.Add(approxPrice); 
          } 
          break; 
        } 
       } 
      } 
     } 

     public void WriteXml(XmlWriter writer) 
     { 
      writer.WriteStartElement("approxPriceList"); 
      foreach (var approxPrice in ApproxPriceList) 
      { 
       writer.WriteStartElement("approxPrice"); 
       writer.WriteAttributeString("currency", approxPrice.Currency); 
       writer.WriteString(approxPrice.ApproxPrice.ToString()); 
       writer.WriteEndElement(); 
      } 
      writer.WriteEndElement(); 
     } 
    } 

    public class ApproxPriceElement 
    { 
     public string Currency { get; set; } 

     public decimal? ApproxPrice { get; set; } 
    } 

这是不是很方便,但它的工作。