BOR15K
BOR15K

Reputation: 468

How do I stop an empty tag of a collection from being emitted by XmlSerializer?

Whilst searching for an advice, I came across various solutions: from IXMLSerializer via ShouldSerialize and up to a simple .Replace() or RegEx. I don't want to use the latter two, as I think they are inefficient, but I don't have enough C# knowledge to implement Serializer related suggestions in my case, so hope one can advise, please.

I have "Details" collection of various travel related options - flight, train, hotel etc... The XSD class has been provided to us by a 3rd party and below is the relevant part:

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

}

Each of the elements has its own XMLRoot, e.g. Hotel one:

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

Details in turn is a part of Product

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

}

In my code I declare objProductDetails collection

Details objProductDetails = new Details();

and populate with the relevant data. some of the elements can remain empty: not every travel has a train or a rented car, so for example I can have only Hotel element populated. I use not null check as below

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

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

Currently, when I execute my code, I do get all the data for the hotel, but an empty tag for everything else :

Hotel:

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

/...... rest of the result

else

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

What would be the best way to skip the empty Details element, to recieve the following please:

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

N.B. Following Ivan's comments below, I have seem to have another issue - although my rent a car object is empty, objRentalCar == null is false. Any help will be much appreciated.

enter image description here

Upvotes: 0

Views: 103

Answers (1)

Ivan R.
Ivan R.

Reputation: 1915

You create empty Details object accordingly it is serialized as empty tag. If you don't want serialize it you should check that all properties in this object would be empty and don't create object or don't set property Details in Product object.

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

Upvotes: 1

Related Questions