简体   繁体   中英

Skipping element when deserializing an XML to list of objects

I have the following XML:

<OUTPUT_XML>
        <VehicleMakes>
            <VehicleMake VehMakeId="1" MakeName="VOLKSWAGEN" VehTypeId="1"/>
            <VehicleMake VehMakeId="2" MakeName="OPEL" VehTypeId="1"/>
            <VehicleMake VehMakeId="3" MakeName="FORD" VehTypeId="1"/>
            <VehicleMake VehMakeId="4" MakeName="VAZ" VehTypeId="1"/>
            <VehicleMake VehMakeId="5" MakeName="FIAT" VehTypeId="1"/>
        </VehicleMakes>
</OUTPUT_XML>

and I need to serialize it to an object, but i need to skip <OUTPUT_XML> and deserialize only VehicleMakes. as List. I used XmlArray and XmlArrayItem in a class that represents OUTPUT_XML and that worked, but If I try to skip that class (OUTPUT_XML) by writing:

 public class GetMakesResponse
        {
            [XmlElement("exec_id")]
            public string ExecId { get; set; }

            [XmlElement("ERROR_CODE")]
            public int ErrorCode { get; set; }

            [XmlElement("VehicleMake")]
            public List<VehicleMake> VehicleMakes { get; set; }
        }

the xml serializer fails and the collection is empty.

Thanks.

ADD:

Currently I use the following classes:

 [Serializable]
        [XmlRoot("root")]
        public class MakesResponse
        {
            [XmlElement("exec_id")]
            public string ExecId { get; set; }

            [XmlElement("ERROR_CODE")]
            public int ErrorCode { get; set; }

            [XmlElement("OUTPUT_XML")]
            public Output Output { get; set; }
        }

[Serializable]
    public class VehicleMake
    {
        [XmlAttribute("VehMakeId")]
        public int VehMakeId { get; set; }

        [XmlAttribute("MakeName")]
        public string MakeName { get; set; }

        [XmlAttribute("VehTypeId")]
        public short VehTypeId { get; set; }
    }

[Serializable]
    public class Output
    {
        [XmlArray(ElementName = "VehicleMakes")]
        [XmlArrayItem(ElementName = "VehicleMake")]
        public List<VehicleMake> VehicleMakes { get; set; }
    }

And the code to deserialize:

public class XmlSerializationUtility<T>
    {
        private readonly XmlSerializer _serializer;

        public XmlSerializationUtility()
        {
            _serializer = new XmlSerializer(typeof(T));
        } 

        public T Deserialize(string xml)
        {
            using (var mStream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
            {
                return (T)_serializer.Deserialize(mStream);
            }
        }

        public string Serialize<TInput>(TInput obj)
        {
            using (var sw = new StringWriter())
            using (var writer = XmlWriter.Create(sw))
            {
                _serializer.Serialize(writer, obj);
                return sw.ToString();
            }
        }
    }

And this works fine but i want to skip Output id possible.

You can use an XmlTextReader to loop through the individual VehicleMake elements and deserialize them individually like this:

XmlSerializer serializer = new XmlSerializer(typeof(VehicleMake));

List<VehicleMake> result = new List<VehicleMake>();

XmlTextReader reader = new XmlTextReader(new MemoryStream(Encoding.UTF8.GetBytes(xml)));

if(reader.ReadToDescendant("VehicleMake"))
{
    do
    {
        result.Add((VehicleMake)serializer.Deserialize(reader));
    } while (reader.ReadToNextSibling("VehicleMake"));
}

Please note that had your XML looked like this ( ArrayOfVehicleMake instead of VehicleMakes ):

<OUTPUT_XML>
    <ArrayOfVehicleMake>
        <VehicleMake VehMakeId="1" MakeName="VOLKSWAGEN" VehTypeId="1"/>
        <VehicleMake VehMakeId="2" MakeName="OPEL" VehTypeId="1"/>
        <VehicleMake VehMakeId="3" MakeName="FORD" VehTypeId="1"/>
        <VehicleMake VehMakeId="4" MakeName="VAZ" VehTypeId="1"/>
        <VehicleMake VehMakeId="5" MakeName="FIAT" VehTypeId="1"/>
    </ArrayOfVehicleMake>
</OUTPUT_XML>

you could have deserialized the entire list without looping through individual elements like this:

XmlSerializer serializer = new XmlSerializer(typeof(List<VehicleMake>));

XmlTextReader reader = new XmlTextReader(new MemoryStream(Encoding.UTF8.GetBytes(xml)));

reader.ReadToDescendant("ArrayOfVehicleMake");

var result = (List<VehicleMake>) serializer.Deserialize(reader);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM