[英]Control Elements in XML c# Serialization
民間,
我試圖創建一個基類,其元素將存在於幾種不同的類類型中。 我已經接近解決方案,但是我需要對XML Serializer類的輸出進行更多控制。
更新
基於以下答案,確定,我已經為XMl添加了Serializable接口,並且進行了進一步的介紹。
下面列出的是我的新測試APP的輸出,正如我期望的那樣,前兩個XML輸出,第三個是接近的,但是它在根元素上缺少名稱空間,並且我需要SomeNewNameForPData就像它是PData一樣工作,即沒有明顯的PData在顯示的最后一個XML中,它還缺少基本請求類中的應用程序。 請參閱最終示例以獲取預期的輸出。
<?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>
預期產量:
<?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>
更新的代碼:
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; }
}
}
所以我的問題是:
使用自定義WriteXml方法時,如何在Payment3的根元素上添加或保留名稱空間,我是否還需要提供編寫基類項目的方法,還是由於我正在序列化該事實而沒有得到這些? XmlSerializer基於其類型使用類?
我需要SomeNewNameForPData充當PData,即沒有明顯的PData
從基本請求類中重新添加到應用程序中。
TIA
如果您在類上實現ISerializable接口,則可以控制序列化的方式。 https://msdn.microsoft.com/zh-CN/library/system.runtime.serialization.iserializable(v=vs.110).aspx
您可以獲得的最接近的是:
<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);
隨着您更新的問題,我可以得到這個xml,不確定這是否是您想要的:
<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; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.