簡體   English   中英

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

[英]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; }
    }
}

所以我的問題是:

  1. 使用自定義WriteXml方法時,如何在Payment3的根元素上添加或保留名稱空間,我是否還需要提供編寫基類項目的方法,還是由於我正在序列化該事實而沒有得到這些? XmlSerializer基於其類型使用類?

  2. 我需要SomeNewNameForPData充當PData,即沒有明顯的PData

  3. 從基本請求類中重新添加到應用程序中。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM