我正在使用Visual Studio 2013并尝试使用C#XML序列化器/反序列化器将存储在类中的变量转换为XML文件或从XML文件转换(我是新手)。
给出一个简单的类:
public class TestXML
{
public String Label = "Hello";
public Boolean Enable = true;
public Int32 PosX = 12;
public Int32 PosY = 34;
}
默认情况下,序列化程序以以下形式生成XML:
<TestXML>
<Label>Hello</Label>
<Enable>true</Enable>
<PosX>12</PosX>
<PosY>34</PosY>
</TestXML>
不幸的是,我的项目要求声明XML文件中的参数必须格式化为:
<TestXML>
<model>
<prop name="Label" value="Hello" />
<prop name="Enable" value="true" />
<prop name="PosX" value="12" />
<prop name="PosY" value="34" />
</model>
</TestXML>
我一直在考虑使用XmlAttribute
和XmlElement
选项来控制XML格式,但无法查看生成所需格式的方法。有没有办法让序列化程序以这种特定的格式存储变量?
答案 0 :(得分:3)
每个king.code手动控制序列化的答案是一个选项(所以我不再重复)。另一种选择是以不同方式构建模型,或者如果不是选项,则创建另一个“数据模型”并将现有模型映射到此并将其序列化。这可能比许多低级XmlReader
/ XmlWriter
代码更容易。
要获得你想要的结果,你需要这样的东西:
public class TestXml
{
[XmlArray("model")]
[XmlArrayItem("prop")]
public List<Prop> Props { get; set; }
}
public class Prop
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
}
此内容:
var xml = new TestXml
{
Props = new List<Prop>
{
new Prop
{
Name = "Label",
Value = "Hello"
}
}
};
然后序列化为:
<TestXML>
<model>
<prop name="Label" value="Hello" />
</model>
</TestXML>
答案 1 :(得分:1)
使用XmlAttributeAttribute
无法做到这一点。您最好实现IXmlSerializable
接口。
public class TestXML : IXmlSerializable
{
public String Label = "Hello";
public Boolean Enable = true;
public Int32 PosX = 12;
public Int32 PosY = 34;
public void WriteXml(XmlWriter writer)
{
// Serialize
}
public void ReadXml(XmlReader reader)
{
// Deserialize
}
public XmlSchema GetSchema()
{
return null;
}
}
通过这种方式,您可以完全控制XML的形状。您可以找到序列化/反序列化班级here所需的所有信息。
答案 2 :(得分:0)
您可以创建三个类
public class TextXML
{
public Model model {get; set;}
}
public class Model
{
public List<prop> props{get; set;}
}
public class prop
{
public string name{get; set;}
public string value{get; set;}
}
并使用XmlAttributes对其进行序列化。将XmlArray用于模型类中的prop类。
如果您有任何其他问题不要害羞,我目前正在开发一个使用大量xml和属性的项目。
答案 3 :(得分:0)
这只能通过实现IXmlSerializable
接口来完成,该接口允许您自定义XML的形状。
public class TestXML : IXmlSerializable
{
public String Label = "Hello";
public Boolean Enable = true;
public Int32 PosX = 12;
public Int32 PosY = 34;
XmlSchema IXmlSerializable.GetSchema()
{
return null;
}
void IXmlSerializable.ReadXml(XmlReader reader)
{
reader.ReadStartElement();
reader.ReadStartElement("model");
if (reader.Name != "prop")
{ throw new InvalidOperationException(); }
do
{
if (!reader.MoveToAttribute("name"))
{ throw new InvalidOperationException(); }
string name = reader.Value;
if (!reader.MoveToAttribute("value"))
{ throw new InvalidOperationException(); }
switch (name)
{
case "Label": Label = reader.Value; break;
case "Enable": Enable = XmlConvert.ToBoolean(reader.Value); break;
case "PosX": PosX = XmlConvert.ToInt32(reader.Value); break;
case "PosY": PosY = XmlConvert.ToInt32(reader.Value); break;
}
}
while (reader.ReadToNextSibling("prop"));
reader.ReadEndElement();
reader.ReadEndElement();
}
void IXmlSerializable.WriteXml(XmlWriter writer)
{
writer.WriteStartElement("model");
WriteProperty(writer, "Label", Label);
WriteProperty(writer, "Enable", XmlConvert.ToString(Enable));
WriteProperty(writer, "PosX", XmlConvert.ToString(PosX));
WriteProperty(writer, "PosY", XmlConvert.ToString(PosY));
writer.WriteEndElement();
}
private void WriteProperty(XmlWriter writer, string name, string value)
{
writer.WriteStartElement("prop");
writer.WriteAttributeString("name", name);
writer.WriteAttributeString("value", value);
writer.WriteEndElement();
}
}
<强>链接:强>