[英]How to serialize class as attribute?
我正在嘗試將一個類序列化為一個屬性。 這是用例:我需要在xml配置文件中存儲大量工程參數。 涉及科學記數法,並且客戶要求輸入的值保持與用戶輸入它們的形式完全相同。 例如,如果有人輸入“ 5.3e-1”,則它必須保持原樣,並且不能轉換為“ 0.53”。 為此,我創建了一個Params類,該類存儲輸入的字符串和雙精度值(實際上存儲雙精度值只是為了以后的處理效率)。 現在的訣竅是:我只希望將字符串值序列化,並且希望將其序列化為屬性。
例如,如果一個對象包含兩個參數A和B,其中字符串值為A.stringVal =“ 1.2e5”和B.stringVal =“ 2.0”,那么我想:
public class MyObject
{
[XmlAttribute]
public MyParam A { get; set; }
[XmlAttribute]
public MyParam B { get; set; }
...more stuff...
}
序列化為:
<myObject A="1.2e5" B="2.0">
more stuff...
</myObject>
我的問題和這里的問題非常相似。 與他不同,我可以實現IXmlSerializable(並且願意),但我無法使其正常工作。 當我嘗試對其進行序列化時,我得到一個神秘的異常,說:“存在錯誤反映類型。” 我究竟做錯了什么?
public class MyParam : IXmlSerializable
{
string name;
string stringVal;
double doubleVal;
public string Val
{
get
{
return stringVal;
}
set
{
stringVal = value;
doubleVal = double.Parse(value);
}
}
public double DoubleVal
{
get
{
return doubleVal;
}
set
{
doubleVal = value;
stringVal = value.ToString();
}
}
public MyParam(string name)
{
this.name = name;
this.stringVal = string.Empty;
this.doubleVal = double.NaN;
}
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteAttributeString(name, stringVal);
}
}
添加無參數構造函數后,出現以下異常: The element 'A' type ConsoleApplication1.MyParam can not be serialized. XmlAttribute / XmlText can not be used to encode types that implement IXmlSerializable.
The element 'A' type ConsoleApplication1.MyParam can not be serialized. XmlAttribute / XmlText can not be used to encode types that implement IXmlSerializable.
刪除IXmlSerializable
我得到一個XmlAttribute/XmlText cannot be used to encode complex types.
異常, XmlAttribute/XmlText cannot be used to encode complex types.
並找到了這個答案
還有這個 。
因此,我認為最好找到另一種序列化屬性的方法。
要獲得所需的內容,需要控制保存屬性的容器(而不是屬性本身)的序列化。 您仍然可以在屬性中封裝序列化代碼,請參見下文。
public class MyObject : IXmlSerializable
{
public MyParam A { get; set; }
public MyParam B { get; set; }
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
//Call each properties "WriteAttribute" call.
A.WriteAttribute(writer);
B.WriteAttribute(writer);
}
}
public class MyParam
{
string name;
string stringVal;
double doubleVal;
public string Val
{
get
{
return stringVal;
}
set
{
stringVal = value;
doubleVal = double.Parse(value);
}
}
public double DoubleVal
{
get
{
return doubleVal;
}
set
{
doubleVal = value;
stringVal = value.ToString();
}
}
public MyParam(string name)
{
this.name = name;
this.stringVal = string.Empty;
this.doubleVal = double.NaN;
}
internal void WriteAttribute(XmlWriter writer)
{
writer.WriteAttributeString(name, stringVal);
}
}
class Program
{
static void Main(string[] args)
{
var test = new MyObject()
{
A = new MyParam("A"),
B = new MyParam("B"),
};
test.A.Val = "1.2e5";
test.B.Val = "2.0";
var ser = new XmlSerializer(typeof(MyObject));
var sb = new StringBuilder();
using (var stream = new StringWriter(sb))
{
ser.Serialize(stream, test);
}
Console.WriteLine(sb);
Console.ReadLine();
}
}
輸出
<?xml version="1.0" encoding="utf-16"?>
<MyObject A="1.2e5" B="2.0" />
如果您不需要屬性本身中的屬性名稱,則可以將代碼修改為以下內容。
public class MyObject : IXmlSerializable
{
//....
public void WriteXml(XmlWriter writer)
{
//Call each properties "WriteAttribute" call.
A.WriteAttribute(writer, "A");
B.WriteAttribute(writer, "B");
}
}
public class MyParam
{
//...
public MyParam()
{
this.stringVal = string.Empty;
this.doubleVal = double.NaN;
}
internal void WriteAttribute(XmlWriter writer, string name)
{
writer.WriteAttributeString(name, stringVal);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.