【问题标题】:Skipping element when deserializing an XML to list of objects将 XML 反序列化为对象列表时跳过元素
【发布时间】:2016-02-05 01:16:50
【问题描述】:

我有以下 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>

我需要将它序列化为一个对象,但我需要跳过 &lt;OUTPUT_XML&gt; 并仅反序列化 VehicleMakes。作为列表。我在代表 OUTPUT_XML 的类中使用了 XmlArray 和 XmlArrayItem 并且有效,但是如果我尝试通过编写跳过该类(OUTPUT_XML):

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

xml 序列化程序失败,集合为空。

谢谢。

添加:

目前我使用以下类:

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

以及要反序列化的代码:

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();
            }
        }
    }

这工作正常,但我想跳过输出 id 可能。

【问题讨论】:

  • 反序列化时不能跳过标签,但是很容易用 public class OUTPUT_XML{ public GetMakesResponse[] VehicleMakes{ get;放; } },那么您将获得一个 OUTPUT_XML 的实例,其中包含一个名为 VehicleMakes 的属性,您的数据在哪里
  • 我这样做了,它正在工作,我的问题是我可以跳过 OUTPU_XML
  • 为什么不只将部分 XML 提供给反序列化器呢?你能展示一下你目前是如何进行反序列化的吗?

标签: c# xml deserialization


【解决方案1】:

您可以使用 XmlTextReader 循环遍历各个 VehicleMake 元素并像这样单独反序列化它们:

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"));
}

请注意,您的 XML 看起来像这样(ArrayOfVehicleMake 而不是 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>

您可以反序列化整个列表,而无需像这样遍历单个元素:

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);

【讨论】:

    猜你喜欢
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多