我正在使用C#+ VSTS2008 + .Net 3.0来进行XML序列化。代码工作正常。下面是我的代码和当前序列化的XML结果。
现在我想在输出XML文件中添加两个额外的图层。这是我期望的XML结果。有什么简单的方法吗?我不确定NestingLevel是否可以帮助这样做。我想找到一种不会改变MyClass和MyObject结构的简单方法。
预期的XML序列化结果,
<?xml version="1.0"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyObjectProperty>
<AdditionalLayer1>
<AdditionalLayer2>
<ObjectName>Foo</ObjectName>
</AdditionalLayer1>
</AdditionalLayer2>
</MyObjectProperty>
</MyClass>
当前XML序列化结果,
<?xml version="1.0"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyObjectProperty>
<ObjectName>Foo</ObjectName>
</MyObjectProperty>
</MyClass>
我目前的代码,
public class MyClass
{
public MyObject MyObjectProperty;
}
public class MyObject
{
public string ObjectName;
}
public class Program
{
static void Main(string[] args)
{
XmlSerializer s = new XmlSerializer(typeof(MyClass));
FileStream fs = new FileStream("foo.xml", FileMode.Create);
MyClass instance = new MyClass();
instance.MyObjectProperty = new MyObject();
instance.MyObjectProperty.ObjectName = "Foo";
s.Serialize(fs, instance);
return;
}
}
答案 0 :(得分:5)
坦率地说,这不会发生。我想找到一种不会改变MyClass和MyObject结构的简单方法。
XmlSerializer
(简单地使用时)遵循类/成员的结构。因此,您无法在不更改结构的情况下添加额外的图层。
当以定制方式(IXmlSerializable
)使用时,您可以肯定的一点是它并不简单......这不是一个有趣的界面来实现。
我的建议:介绍一个模仿所需格式的DTO,并在序列化之前填充它。
答案 1 :(得分:4)
为什么还需要这两个额外的图层?
这是业务需求,您应该将这两个对象添加到对象模型中:
public class MyClass
{
public AdditionalLayer1 AdditionalLayer1;
}
public class AdditionalLayer1
{
public AdditionalLayer2 AdditionalLayer2;
}
public class AdditionalLayer2
{
public MyObject MyObjectProperty;
}
public class MyObject
{
public string ObjectName;
}
如果纯粹是因为某些兼容性要求,你可以做上面的事情,或者在MyClass上实现IXmlSerializable:
public class MyClass : IXmlSerializable
{
public MyObject MyObjectProperty;
public void WriteXml (XmlWriter writer)
{
//open the two layers
//serialize MyObject
//close the two layers
}
public void ReadXml (XmlReader reader)
{
//read all the layers back, etc
}
public XmlSchema GetSchema()
{
return(null);
}
}
答案 2 :(得分:2)
您可以在序列化后使用XSL进行转换并添加“缺失”标记。
答案 3 :(得分:1)
我建议序列化为MemoryStream
而不是FileStream
,然后将XML加载到XmlDocument
,然后使用该类的方法插入所需的额外节点。之后,您可以将其保存。
答案 4 :(得分:0)
我最近才这样做,并没有发现在所有困难或复杂的情况下覆盖IXmlSerializable接口。序列化/反序列化正常但对于包含子类的类,您需要在IXmlSerializable派生的额外标记中包含该类:
class ContainingClass : IXmlSerializable
{
...
#region IXmlSerializable Members
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
**reader.ReadStartElement("Equipment");**
XmlSerializer ser = new XmlSerializer(typeof(Host));
while (reader.NodeType != XmlNodeType.EndElement)
{
Host newHost = new Host();
newHost.Name = (string) ser.Deserialize(reader);
_hosts.Add(newHost);
reader.Read();
}
// Read the node to its end.
// Next call of the reader methods will crash if not called.
**reader.ReadEndElement(); // "Equipment"**
}
public void WriteXml(XmlWriter writer)
{
XmlSerializer ser = new XmlSerializer(typeof(Host));
**writer.WriteStartElement("Equipment");**
foreach (Host host in this._hosts)
{
ser.Serialize(writer, host);
}
**writer.WriteEndElement();**
}
#endregion
我在这里所做的就是包装低级对象的de / serialization。在这里,我在这个类的集合中的所有主机周围包装了一个额外的标签“Equipment”。只要您关闭每个标签,就可以在此处添加任意数量的标签。
注意:Bold显示为**文本** - 只是确保你摆脱双星号:)