【问题标题】:c# XML Serializing with derived classes using different namespacec# XML 序列化与使用不同命名空间的派生类
【发布时间】:2015-08-21 07:28:25
【问题描述】:

我正在尝试读取一个 xml 文件并将其反序列化为我的 InsertSensorType 类,而不是读取 VALUE1,VALUE2 .. 我尝试将 XmlElement 名称添加到 InsertSensorTypeMetadata 类中的 InsertionMetadata 属性中,但它不起作用。我已经搜索并找到了解决方案,但它们对这个问题无效。谁能告诉我我做错了什么。

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

【问题讨论】:

    标签: c# xml xml-serialization derived-class xml-deserialization


    【解决方案1】:

    试试这个

    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
        {
    
        }
    }
    ​
    

    【讨论】:

    • 嗨@jdweng,感谢您的回复,我看到您更改了一些类和属性,但我不应该更改我使用xsd 生成的类。
    • 那为什么我的代码有效而你的代码失败了?自动生成的类并不适用于所有情况。它们只是起点,通常需要编辑。
    • 是的,你是对的,所以我添加了 [System.Xml.Serialization.XmlElement(ElementName = "SosInsertionMetadata", Type = typeof(SosInsertionMetadataType), Namespace = "opengis.net/sos/2.0")] line to over InsertionMetadata 属性InsertSensorTypeMetadata 类。并更改了我的反序列化方法,现​​在它可以工作了。再次感谢!
    【解决方案2】:

    我的解决办法是:

    在 InsertSensorTypeMetadata 类中的 InsertionMetadata 属性上添加了这一行

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

    【讨论】:

      猜你喜欢
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      相关资源
      最近更新 更多