Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XML c#序列化中的控制元素_C#_.net_Xml_Inheritance_Serialization - Fatal编程技术网

XML c#序列化中的控制元素

XML c#序列化中的控制元素,c#,.net,xml,inheritance,serialization,C#,.net,Xml,Inheritance,Serialization,各位 我正在尝试创建一个基类,其中的元素将跨多个不同的类类型存在。我接近解决方案,但我需要对XML序列化程序类的输出进行更多的控制 更新 好的,根据下面的答案,我添加了XMl的可序列化接口,并且做了进一步的改进 下面列出的是我的新测试应用程序的输出,前两个XML输出与我预期的一样,第三个很接近,但它在根元素处缺少名称空间,我需要一些NewNameForpData来充当它是PData的角色,即没有与上一个XML中显示的一样明显的PData,并且它也缺少基本请求类中的应用程序。有关预期输出,请参见

各位

我正在尝试创建一个基类,其中的元素将跨多个不同的类类型存在。我接近解决方案,但我需要对XML序列化程序类的输出进行更多的控制

更新


好的,根据下面的答案,我添加了XMl的可序列化接口,并且做了进一步的改进

下面列出的是我的新测试应用程序的输出,前两个XML输出与我预期的一样,第三个很接近,但它在根元素处缺少名称空间,我需要一些NewNameForpData来充当它是PData的角色,即没有与上一个XML中显示的一样明显的PData,并且它也缺少基本请求类中的应用程序。有关预期输出,请参见最后一个示例

<?xml version="1.0" encoding="utf-8"?>
<Payment1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Application="MyApp">
  <Pdata Language="en">
    <TimeStamp>2016-06-17T15:31:37.7767381+01:00</TimeStamp>
  </Pdata>
  <RequestType>Pay1</RequestType>
</Payment1>

<?xml version="1.0" encoding="utf-8"?>
<Payment2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Application="MyApp">
  <Sender>ProgramClass</Sender>
  <RequestType>Pay2</RequestType>
</Payment2>

<?xml version="1.0" encoding="utf-8"?>
<Payment3>
  <SomeNewNameForPData>
    <P_Data Language="en">
      <TimeStamp>2016-06-17T15:31:37.7767381+01:00</TimeStamp>
    </P_Data>
  </SomeNewNameForPData>
</Payment3>

2016-06-17T15:31:37.7767381+01:00
工资1
程序类
工资2
2016-06-17T15:31:37.7767381+01:00
预期产出:

<?xml version="1.0" encoding="utf-8"?>
<Payment3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Application="MyApp">
  <SomeNewNameForPData Language="en">
      <TimeStamp>2016-06-17T15:31:37.7767381+01:00</TimeStamp>
  </SomeNewNameForPData>
</Payment3>

2016-06-17T15:31:37.7767381+01:00
更新代码:

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

namespace ConsoleApplication7
{
    class Program
    {
        static void Main(string[] args)
        {
            Request cp = new Payment1() { Application = "MyApp", DataField = new P_Data() { Language = "en" } };

            Request cp2 = new Payment2() { Application = "MyApp", Sender = "ProgramClass" };

            Request cp3 = new Payment3() { Application = "MyApp", DataField = new P_Data() { Language = "en" } };

            string s1 = cp.MessageAsString();

            string s2 = cp2.MessageAsString();

            string s3 = cp3.MessageAsString();

            Console.WriteLine(s1);
            Console.WriteLine("");
            Console.WriteLine(s2);
            Console.WriteLine("");
            Console.WriteLine(s3);

            Console.ReadKey();
        }
    }

    public class Helpers : StringWriter
    {
        public override Encoding Encoding
        {
            get { return Encoding.UTF8; }
        }
    }

    public abstract class Request
    {
        [XmlAttribute()]
        public string Application { get; set; }

        public virtual string MessageAsString()
        {
            return CreateMessage();
        }

        private string CreateMessage()
        {
            return SerializeObject<Request>(this, null);
        }

        public static string SerializeObject<X>(X toSerialize, XmlSerializerNamespaces xmlNameSpace)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
            StringWriter textWriter = new StringWriter();

            string utf8 = ""; ;
            using (StringWriter writer = new Helpers())
            {
                xmlSerializer.Serialize(writer, toSerialize, xmlNameSpace);
                utf8 = writer.ToString();
            }

            return utf8;
        }

    }

    public abstract class RequestType1 : Request
    {
        public RequestType1()
        {
        }

        [XmlIgnore()]
        public abstract string RequestType { get; set; }

        [XmlElement("Pdata")]
        public virtual P_Data DataField { get; set; }
    }

    public abstract class RequestType2 : Request
    {
        public RequestType2()
        {
        }

        [XmlIgnore()]
        public abstract string RequestType { get; set; }

        public string Sender { get; set; }
    }

    [Serializable]
    public abstract class RequestType3 : RequestType1, IXmlSerializable
    {
        public RequestType3()
        {
        }

        [XmlElement("SomeNewNameForPData")]
        public override P_Data DataField { get; set; }

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            throw new NotImplementedException();
        }

        public void ReadXml(XmlReader reader)
        {
            throw new NotImplementedException();
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement("SomeNewNameForPData");

            var ns = new XmlSerializerNamespaces();
            ns.Add("", "");
            new XmlSerializer(typeof(P_Data)).Serialize(writer, this.DataField, ns);

            writer.WriteEndElement();
        }
    }

    public class Payment1 : RequestType1
    {
        public Payment1()
        {
        }

        public override string RequestType
        {
            get
            {
                return "Pay1";
            }
            set { }

        }
    }

    public class Payment2 : RequestType2
    {
        public Payment2()
        {
        }

        public override string RequestType
        {
            get
            {
                return "Pay2";
            }
            set { }

        }
    }

    public class Payment3 : RequestType3
    {
        public Payment3()
        {
        }

        public override string RequestType
        {
            get
            {
                return "Pay3";
            }
            set { }

        }
    }

    public class P_Data
    {
        public P_Data()
        {
            //We need to format the datetime field
            TimeStamp = DateTime.Now;
        }

        [XmlAttribute, DefaultValue("")]
        public string Language { get; set; }

        public DateTime TimeStamp { get; set; }
    }
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.Xml.Serialization;
使用System.IO;
使用系统组件模型;
使用System.Xml;
命名空间控制台应用程序7
{
班级计划
{
静态void Main(字符串[]参数)
{
请求cp=newpayment1(){Application=“MyApp”,DataField=new P_Data(){Language=“en”};
请求cp2=newpayment2(){Application=“MyApp”,Sender=“ProgramClass”};
请求cp3=newpayment3(){Application=“MyApp”,DataField=new P_Data(){Language=“en”};
字符串s1=cp.MessageAsString();
字符串s2=cp2.MessageAsString();
字符串s3=cp3.MessageAsString();
控制台写入线(s1);
控制台。写线(“”);
控制台写入线(s2);
控制台。写线(“”);
控制台写入线(s3);
Console.ReadKey();
}
}
公共类助手:StringWriter
{
公共覆盖编码
{
获取{return Encoding.UTF8;}
}
}
公共抽象类请求
{
[XmlAttribute()]
公共字符串应用程序{get;set;}
公共虚拟字符串MessageAsString()
{
返回CreateMessage();
}
私有字符串CreateMessage()
{
返回序列化对象(this,null);
}
公共静态字符串序列化对象(X toSerialize,XmlSerializerNamespaces XmlNamespaces)
{
XmlSerializer XmlSerializer=新的XmlSerializer(toSerialize.GetType());
StringWriter textWriter=新StringWriter();
字符串utf8=“”;
使用(StringWriter=new Helpers())
{
serializer.Serialize(writer、toSerialize、xmlNameSpace);
utf8=writer.ToString();
}
返回utf8;
}
}
公共抽象类RequestType1:请求
{
公共请求类型1()
{
}
[XmlIgnore()]
公共抽象字符串请求类型{get;set;}
[XmlElement(“Pdata”)]
公共虚拟P_数据字段{get;set;}
}
公共抽象类RequestType2:请求
{
公共请求类型2()
{
}
[XmlIgnore()]
公共抽象字符串请求类型{get;set;}
公共字符串发送方{get;set;}
}
[可序列化]
公共抽象类RequestType3:RequestType1,IXmlSerializable
{
公共请求类型3()
{
}
[xmlement(“SomeNewNameForPData”)]
公共覆盖P_数据数据字段{get;set;}
public System.Xml.Schema.XmlSchema GetSchema()
{
抛出新的NotImplementedException();
}
公共void ReadXml(XmlReader)
{
抛出新的NotImplementedException();
}
public void WriteXml(XmlWriter)
{
writerstartelement(“SomeNewNameForPData”);
var ns=新的XmlSerializerNamespaces();
加上(“,”);
新的XmlSerializer(typeof(P_Data)).Serialize(writer,this.DataField,ns);
writer.writeedelement();
}
}
公共类付款1:RequestType1
{
公共支出1()
{
}
公共重写字符串请求类型
{
得到
{
返回“Pay1”;
}
集合{}
}
}
公共类付款2:RequestType2
{
公共支出2()
{
}
公共重写字符串请求类型
{
得到
{
返回“Pay2”;
}
集合{}
}
}
公共类付款3:RequestType3
{
公共支出3()
{
}
公共重写字符串请求类型
{
得到
{
返回“Pay3”;
}
集合{}
}
}
公共类P_数据
{
公共P_数据()
{
//我们需要格式化datetime字段
TimeStamp=DateTime.Now;
}
[XmlAttribute,DefaultValue(“”)
公共字符串语言{get;set;}
公共日期时间时间戳{get;set;}
}
}
因此,我的问题是:

  • 如何在Payment3的根元素处添加或保留命名空间在使用自定义WriteXml方法时,我是否还需要提供编写基类项的方法,还是因为我正在使用XmlSerializer根据其类型序列化类而无法获得这些项

  • 我需要一个新名字,让PData看起来像是PData(没有明显的PData)

  • 从基本请求类添加回应用程序


  • TIA

    如果在类上实现ISerializable接口,则可以控制序列化的方式
    <MyRequestName Sender="MyAppName" IP="123.456.7.0">
      <NodeWhatever>
        <BaseElement type="SomeData" LanguageCode="en" />
        <BaseElement type="SomeOtherData" Amount="1000" />
      </NodeWhatever>
    </MyRequestName>
    
    public abstract class Root
    {
    
        public string Sender { get; set; }
    
    
        public string IP { get; set; }
    
        [Persist("", ChildName = "NodeWhatever")]
        public List<Node> Nodes { get; set; }
    }
    
    [PersistInclude(typeof(SomeData),typeof(SomeOtherData))]
    public class Node
    {
        [Persist("")]
        public List<BaseElement> Elements { get; set; }
    }
    
    XmlArchive serial = new XmlArchive(R.GetType());
    Archive.ClassKwd = "type";
    
    string utf8 = ""; ;
    
    using (var mm = new MemoryStream())
    {
        serial.Write(mm,R,"MyRequestName");
        mm.Position = 0;
    
        using (var reader = new StreamReader(mm))
        {
            utf8 = reader.ReadToEnd();
        }   
    }
    
    Console.WriteLine(utf8);    
    
    <Payment1 RequestType="Pay1" Application="MyApp">
      <DataField Language="en" TimeStamp="06/17/2016 10:38:39" />
    </Payment1>
    
    <Payment2 RequestType="Pay2" Sender="ProgramClass" Application="MyApp" />
    
    <Payment3 RequestType="Pay3" Application="MyApp">
      <MyNameWhatever Language="en" TimeStamp="06/17/2016 10:38:39" />
    </Payment3>
    
    public abstract class Request
    {
        public string Application { get; set; }
    
        public virtual string MessageAsString()
        {
            return CreateMessage();
        }
    
        private string CreateMessage()
        {
            return SerializeObject<Request>(this);
        }
    
        public static string SerializeObject<X>(X toSerialize)
        {
            var xmlSerializer = new XmlArchive(toSerialize.GetType());
            Archive.Provider = CultureInfo.InvariantCulture;
    
            string utf8 = ""; ;
            using (var  writer = new MemoryStream())
            {
                xmlSerializer.Write(writer, toSerialize);
                writer.Position = 0;
    
                var reader = new StreamReader(writer);
                utf8 = reader.ReadToEnd();
            }
    
            return utf8;
        }
    
    }
    
    public abstract class RequestType1 : Request
    {
        public abstract string RequestType { get; set; }   
        public virtual P_Data DataField { get; set; }
    }
    
    public abstract class RequestType2 : Request
    {        
        public abstract string RequestType { get; set; }
        public string Sender { get; set; }
    }
    
    
    public abstract class RequestType3 : RequestType1
    {
        [Persist("MyNameWhatever")]
        public override P_Data DataField { get; set; }
    
    }
    
    public class Payment1 : RequestType1
    {
        public override string RequestType
        {
            get { return "Pay1"; }
            set { }
        }
    }
    
    public class Payment2 : RequestType2
    {
        public override string RequestType
        {
            get { return "Pay2"; }
            set { }
        }
    }
    
    public class Payment3 : RequestType3
    {
        public override string RequestType
        {
            get { return "Pay3"; }
            set { }
        }
    }
    
    public class P_Data
    {
        public P_Data() { TimeStamp = DateTime.Now; }
        public string Language { get; set; }
        public DateTime TimeStamp { get; set; }
    }