c# XML 使用不同的命名空间使用派生的 类 进行序列化

c# XML Serializing with derived classes using different namespace

我正在尝试读取一个 xml 文件并将其反序列化为我的 InsertSensorType class 然后读取 VALUE1、VALUE2 ...我试图将 Xml 元素名称添加到我的InsertSensorTypeMetadata class 中的 InsertionMetadata 属性,但 work.I 没有搜索并找到解决方案,但它们对这个问题无效。谁能告诉我我做错了什么。

Xml 文件:

<?xml version="1.0" encoding="utf-8" ?>
<swes:InsertSensor     
    xmlns:swes="http://www.opengis.net/swes/2.0"
    xmlns:sos="http://www.opengis.net/sos/2.0" >
  <swes:metadata>
    <sos:SosInsertionMetadata>
      <sos:observationType>VALUE1</sos:observationType>
      <sos:observationType>VALUE2</sos:observationType>
      <sos:featureOfInterestType>VALUE3</sos:featureOfInterestType>
      <sos:featureOfInterestType>VALUE4</sos:featureOfInterestType>
    </sos:SosInsertionMetadata>
  </swes:metadata>
</swes:InsertSensor>

我的类:

namespace Problem1.Classes
{
    [SerializableAttribute()]
    [XmlTypeAttribute(Namespace = "http://www.opengis.net/swes/2.0")]
    [XmlRootAttribute("InsertSensor", Namespace = "http://www.opengis.net/swes/2.0", IsNullable = false)]
    public class InsertSensorType
    {
        [System.Xml.Serialization.XmlElementAttribute("metadata")]
        public InsertSensorTypeMetadata[] metadata { get; set; }
    }

    [SerializableAttribute()]
    [XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.opengis.net/swes/2.0")]
    public class InsertSensorTypeMetadata
    {

        [XmlElement(ElementName = "SosInsertionMetadata", Type = typeof(SosInsertionMetadataType))]
        public InsertionMetadataType InsertionMetadata { get; set; }

    }

    [XmlIncludeAttribute(typeof(SosInsertionMetadataType))]
    [SerializableAttribute()]
    [XmlTypeAttribute(Namespace = "http://www.opengis.net/swes/2.0")]
    public abstract partial class InsertionMetadataType
    {
    }

    [SerializableAttribute()]
    [XmlTypeAttribute(Namespace = "http://www.opengis.net/sos/2.0")]
    public partial class SosInsertionMetadataType : InsertionMetadataType
    {
        [System.Xml.Serialization.XmlElementAttribute("observationType", DataType = "anyURI")]
        public string[] observationType { get; set; }

        [System.Xml.Serialization.XmlElementAttribute("featureOfInterestType", DataType = "anyURI")]
        public string[] featureOfInterestType { get; set; }
    }

}

这是我的主要代码:

 static void Main(string[] args)
        {
            XmlElement xmlRequest = null;
            XmlDocument doc = new XmlDocument();
            doc.Load("request.xml");
            xmlRequest = doc.DocumentElement;
            executeRequest(xmlRequest);
        }

        static void executeRequest(XmlElement xmlRequest)
        {
            InsertSensorType insertSensorRequest = ValidateRequest<InsertSensorType>(xmlRequest);

            InsertSensorTypeMetadata[] _InsertSensorTypeMetadata = insertSensorRequest.metadata; 
            Console.WriteLine("Length of metadata :" + _InsertSensorTypeMetadata.Length);//1
            foreach (InsertSensorTypeMetadata istm in _InsertSensorTypeMetadata)
            {

                SosInsertionMetadataType sos = istm.InsertionMetadata as SosInsertionMetadataType;
                //sos is null

            }
            Console.Read();
        }

        static T ValidateRequest<T>(XmlElement xmlRequest) where T : class
        {
            string xml = xmlRequest.OuterXml;
            StringReader reader = new StringReader(xml);
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            //XmlSerializer serializer = new XmlSerializer(typeof(T), new Type[] { typeof(SosInsertionMetadataType) });
            T typeInstance = (T)serializer.Deserialize(reader);

            return typeInstance;
        }

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            InsertSensorType insertSensorType = new InsertSensorType() {
                metadata = new Metadata() {
                    insertSensorTypeMetadata = new InsertSensorTypeMetadata() {
                        InsertionMetadata = new List<InsertionMetadataType>() {
                            new ObservationType() { value = "Value1"},
                            new ObservationType() { value = "Value2"},
                            new FeatureOfInterestType() { value = "Value3"},
                            new FeatureOfInterestType() { value = "Value4"}
                        }
                    }
                }
            };
            XmlSerializer serializer = new XmlSerializer(typeof(InsertSensorType));
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("swes","http://www.opengis.net/swes/2.0");
            ns.Add("sos","http://www.opengis.net/sos/2.0");

            StreamWriter writer = new StreamWriter(FILENAME);
            serializer.Serialize(writer, insertSensorType, ns);
            writer.Flush();
            writer.Close();
            writer.Dispose();

            XmlSerializer xs = new XmlSerializer(typeof(InsertSensorType));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            InsertSensorType newInsertSensorType = (InsertSensorType)xs.Deserialize(reader);

        }

    }
    [XmlRoot(ElementName = "InsertSensor")]
    public class InsertSensorType
    {
        [XmlElement("metadata")]
        public Metadata metadata { get; set; }
    }
    [XmlRoot("metadata", Namespace = "http://www.opengis.net/swes/2.0")]
    public class Metadata
    {
        [XmlElement("SosInsertionMetadata")]
        public InsertSensorTypeMetadata insertSensorTypeMetadata { get; set; }
    }

    [XmlRoot("SosInsertionMetadata", Namespace = "http://www.opengis.net/sos/2.0")]
    public class InsertSensorTypeMetadata
    {
         [XmlElement()]
         public List<InsertionMetadataType> InsertionMetadata { get; set; }

    }

    [XmlInclude(typeof(ObservationType))]
    [XmlInclude(typeof(FeatureOfInterestType))]
    [Serializable]
    [XmlRoot(Namespace = "http://www.opengis.net/sos/2.0")]
    public class InsertionMetadataType
    {
        public string value { get; set; }
    }
    [Serializable]
    [XmlRoot(ElementName = "observationType", Namespace = "http://www.opengis.net/sos/2.0")]
    public class ObservationType : InsertionMetadataType
    {

    }
    [Serializable]
    [XmlRoot(ElementName = "featureOfInterestType", Namespace = "http://www.opengis.net/sos/2.0")]
    public class FeatureOfInterestType : InsertionMetadataType
    {

    }
}
​

我的解决方案是:

将此行添加到 InsertSensorTypeMetadata 中的 InsertionMetadata 属性 class

[System.Xml.Serialization.XmlElement(ElementName = "SosInsertionMetadata", Type = typeof(SosInsertionMetadataType), Namespace = "http://www.opengis.net/sos/2.0")] // added 

更改我的反序列化方法

public static T ValidateRequest<T>(XmlElement element) where T : class
{
    var serializer = new XmlSerializer(typeof(T));

    return (T)serializer.Deserialize(new XmlNodeReader(element));
}

并更改了打印值的方式

static void executeRequest(XmlElement xmlRequest)
{
    InsertSensorType insertSensorRequest = ValidateRequest<InsertSensorType>(xmlRequest);
    foreach (InsertSensorTypeMetadata istm in insertSensorRequest.metadata)
    {
        SosInsertionMetadataType sos = (SosInsertionMetadataType)istm.InsertionMetadata;
        foreach(string s in sos.featureOfInterestType)
            Console.WriteLine(s);

        foreach (string s in sos.observationType)
            Console.WriteLine(s);

    }
}