我正在尝试将类序列化为属性。以下是用例:我需要在xml配置文件中存储大量工程参数。涉及科学记数法,并且客户要求输入的值保持用户输入的确切形式。例如,如果有人输入" 5.3e-1"然后它必须保持这样,并且不能转换成,例如," 0.53"。为此,我创建了一个Params类,它存储输入的字符串和double值(实际存储double值仅用于以后的处理效率)。现在就是诀窍:我只希望序列化字符串值,并希望将其序列化为属性。
例如,如果一个对象包含两个参数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>
我的问题与here提出的问题非常相似。与他不同,我很好地实现了IXmlSerializable(并且更愿意),我只是无法使它工作。当我尝试序列化它时,我得到一个神秘的例外,&#34;有错误反射类型。&#34;我做错了什么?
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);
}
}
答案 0 :(得分:0)
在我添加无参数构造函数后,我得到以下异常:
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.
并找到this answer
和this。
所以,我认为,最好找到另一种序列化属性的方法。
答案 1 :(得分:0)
要获得您想要的内容,您需要控制包含属性的容器上的序列化,而不是属性本身。您仍然可以将序列化代码封装在属性中,如下所示。
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);
}
}