如何阻止XmlSerializer发出集合的空标签?

时间:2019-06-04 16:36:02

标签: c# serialization collections

在寻找建议时,我遇到了各种解决方案:从IXMLSerializerShouldSerialize直到简单的.Replace()或RegEx。 我不想使用后两者,因为我认为它们效率不高,但是我没有足够的C#知识来实现​​与我的序列化程序相关的建议,因此希望有人可以提出建议。

我有与旅行有关的各种选择的“详细信息”集合-航班,火车,酒店等... XSD类是由第三方提供给我们的,以下是相关部分:

[XmlRoot(ElementName = "Details")]
public class Details
{
    [XmlElement(ElementName = "Flight")]
    public Flight Flight { get; set; }
    [XmlElement(ElementName = "Train")]
    public Train train { get; set; }
    [XmlElement(ElementName = "RentalCar")]
    public RentalCar rentalCar { get; set; }
    [XmlElement(ElementName = "Hotel")]
    public Hotels Hotel { get; set; }
    [XmlElement(ElementName = "Bus")]
    public Bus Bus { get; set; }

}

每个元素都有其自己的XMLRoot,例如旅馆一:

 [XmlRoot(ElementName = "Hotel")]
    public class Hotels
    {
        [XmlElement(ElementName = "VoucherNo")]
        public string VoucherNo { get; set; }
        [XmlElement(ElementName = "VoucherRef")]
        public string VoucherRef { get; set; }
        [XmlElement(ElementName = "DepartureDate")]
        public string departureDate;
        [XmlElement(ElementName = "DepartureDateFieldSpecified")]
        public bool departureDateFieldSpecified;
        [XmlElement(ElementName = "ReturnDate")]
        public string returnDate;
        [XmlElement(ElementName = "ReturnDateFieldSpecified")]
        public bool returnDateFieldSpecified;
    }

详细信息又是产品的一部分

[XmlRoot(ElementName = "Product")]
public class Product
{
    [XmlElement(ElementName = "ArticleNumber")]
    public int articleNumber { get; set; }
//many other elements
    public Details Details { get; set; }

}

在我的代码中,我声明了objProductDetails集合

Details objProductDetails = new Details();

并填充相关数据。有些元素可以保留为空:并非每次旅行都有火车或租车,因此例如,我只能填充Hotel元素。我使用如下非空检查

if (objHotel != null)
      objProductDetails.Hotel = objHotel;

if (objRentalCar != null)
      objProductDetails.rentalCar = objRentalCar;

当前,当我执行代码时,我确实获取了酒店的所有数据,但获取了所有其他内容的空标记:

酒店:

<qfl:Product>
  <qfl:ArticleNumber>100</qfl:ArticleNumber>
     <qfl:Details>
        <qfl:Hotel>
          <qfl:VoucherNo>1234</qfl:VoucherNo>

/...... rest of the result

其他

 <qfl:Product>
    <qfl:ArticleNumber>180</qfl:ArticleNumber>
       <qfl:Details />
  </qfl:Product>
        /...... rest of the result

跳过空的Details元素的最佳方法是什么,以获取以下信息:

 <qfl:Product>
     <qfl:ArticleNumber>180</qfl:ArticleNumber>
 </qfl:Product>

在以下Ivan的评论之后,我似乎还有另一个问题-尽管我租车对象为空,但objRentalCar == null为false。任何帮助都感激不尽。

enter image description here

1 个答案:

答案 0 :(得分:1)

您将创建一个空的Details对象,因此该对象被序列化为空标记。如果您不想序列化它,则应检查该对象中的所有属性是否为空,并且不要创建对象,也不要在Details对象中设置属性Product

if (objHotel != null || objRentalCar != null || ...)
{
    product.Details = objProductDetails;
}