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