我正在尝试XML序列化一个包含两个具有相同名称的结构的类:
public class MyClass
{
public System.Windows.Size WSize = new System.Windows.Size();
public System.Drawing.Size DSize = new Size.Drawing.Size();
}
产生的错误:
Types 'System.Drawing.Size' and 'System.Windows.Size' both use the XML type name,
'Size', from namespace ''. Use XML attributes to specify a unique XML name and/or
namespace for the type.
到目前为止我发现的所有内容都涉及使用XML属性来装饰Type
。我不能直接装饰任何结构,因为它们不是我的代码。
我觉得我在这里很容易丢失一些东西......是否有可以应用于字段的XML属性?
修改 我使用几个代理属性添加了答案。我对这个特定的实施不满意,因为它让公共财产停滞不前。
我也考虑过DataContractSerialization
,但我还是犹豫不决下一步。其他人有他们可以建议的东西吗?
编辑2
我的措辞可能有些混乱。我可以修改和修饰MyClass
,WSize
和DSize
。但是,显然,我无法修改System.Windows.Size
或System.Drawing.Size
。
答案 0 :(得分:2)
你可以通过自定义XML序列化的代理来完成,我创建了这个完全有效的例子,虽然有很多错误检查要完成它的起点。
public class MyClass
{
public System.Windows.Size WSize = new System.Windows.Size();
public System.Drawing.Size DSize = new System.Drawing.Size();
}
public class MyClassProxy : MyClass, IXmlSerializable
{
public new System.Windows.Size WSize { get { return base.WSize; } set { base.WSize = value; } }
public new System.Drawing.Size DSize { get { return base.DSize; } set { base.DSize = value; } }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
reader.MoveToContent();
reader.ReadStartElement();
string wheight = reader["height"];
string wwidth = reader["width"];
int w, h;
w = int.Parse(wwidth);
h = int.Parse(wheight);
WSize = new Size(w, h);
reader.ReadStartElement();
string dheight = reader["height"];
string dwidth = reader["width"];
w = int.Parse(dwidth);
h = int.Parse(dheight);
DSize = new System.Drawing.Size(w, h);
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement("MyClassProxy");
writer.WriteStartElement("WSize");
writer.WriteAttributeString("height", WSize.Height.ToString());
writer.WriteAttributeString("width", WSize.Width.ToString());
writer.WriteEndElement();
writer.WriteStartElement("DSize");
writer.WriteAttributeString("height", DSize.Height.ToString());
writer.WriteAttributeString("width", DSize.Width.ToString());
writer.WriteEndElement();
writer.WriteEndElement();
}
}
class Program
{
static void Main(string[] args)
{
MyClassProxy p = new MyClassProxy();
p.DSize = new System.Drawing.Size(100, 100);
p.WSize = new Size(400, 400);
string xml = "";
using (StringWriter sw = new StringWriter())
{
System.Xml.XmlWriter wr = System.Xml.XmlWriter.Create(sw);
p.WriteXml(wr);
wr.Close();
xml = sw.ToString();
}
MyClassProxy p2 = new MyClassProxy();
using (StringReader sr = new StringReader(xml))
{
System.Xml.XmlReader r = System.Xml.XmlReader.Create(sr);
p2.ReadXml(r);
}
MyClass baseClass = (MyClass)p2;
Print(baseClass);
Console.ReadKey();
}
static void Print(MyClass c)
{
Console.WriteLine(c.DSize.ToString());
Console.WriteLine(c.WSize.ToString());
}
}
答案 1 :(得分:0)
在这里,我可能并不十分满意(不是很干净):
public class MyClass
{
public System.Windows.Size WSize = new System.Windows.Size();
[XmlIgnore]
public System.Drawing.Size DSize = new Size();
public int DSizeWidthForSerialization
{
get
{
return DSize.Width;
}
set
{
DSize.Width = value;
}
}
public int DSizeHeightForSerialization
{
get
{
return DSize.Height;
}
set
{
DSize.Height = value;
}
}
}
答案 2 :(得分:0)
我最终创建了一个容纳System.Drawing.Size
的新课程。在那个新类中,我创建了隐式运算符并处理了一些构造函数。这允许我序列化,而不必更改任何现有代码:
public class MyClass
{
public System.Windows.Size WSize = new System.Windows.Size();
public MyDrawingSize DSize = new System.Drawing.Size();
public class MyDrawingSize
{
public int Height, Width;
public MyDrawingSize() { } //Needed for deserialization
public MyDrawingSize(int width, int height)
{
Width = width;
Height = height;
}
public static implicit operator System.Drawing.Size(MyDrawingSize size)
{
return new System.Drawing.Size(size.Width, size.Height);
}
public static implicit operator MyDrawingSize(System.Drawing.Size size)
{
return new MyDrawingSize() { Width = size.Width, Height = size.Height };
}
}
}