我正在使用一个类库,它代表了.xml中的一些配置。使用XmlSerializer
读入配置。幸运的是,代表.xml的类使用XmlAnyElement
属性,允许我扩展配置数据以用于我自己的目的,而无需修改原始类库。
<?xml version="1.0" encoding="utf-8"?>
<Config>
<data>This is some data</data>
<MyConfig>
<data>This is my data</data>
</MyConfig>
</Config>
这适用于反序列化。我可以允许类库正常反序列化.xml,我可以使用我自己的XmlSerializer
实例和XmlNodeReader
对内部XmlNode
。
public class Config
{
[XmlElement]
public string data;
[XmlAnyElement]
public XmlNode element;
}
public class MyConfig
{
[XmlElement]
public string data;
}
class Program
{
static void Main(string[] args)
{
using (Stream fs = new FileStream(@"c:\temp\xmltest.xml", FileMode.Open))
{
XmlSerializer xser1 = new XmlSerializer(typeof(Config));
Config config = (Config)xser1.Deserialize(fs);
if (config.element != null)
{
XmlSerializer xser2 = new XmlSerializer(typeof(MyConfig));
MyConfig myConfig = (MyConfig)xser2.Deserialize(new XmlNodeReader(config.element));
}
}
}
我需要创建一个实用程序,允许用户生成一个新的配置文件,其中包括类库配置以及我自己的配置,因此将创建未从.xml文件中读取的新对象。问题是我如何将数据序列化回.xml?
我意识到在调用类库配置上的相同方法之前,我必须首先在我的数据上调用XmlSerializer.Serialize
。但是,这需要在调用XmlNode
后由Serialize
表示我的数据。使用XmlNode
将对象序列化为XmlSerializer
的最佳方法是什么?
谢谢,
-kevin
btw--看起来像Chris Lovett编写的XmlNodeWriter
课程曾一度可以从微软获得,但链接现在已被破坏。有没有人知道另一个获得此课程的地点?
答案 0 :(得分:11)
因此,您需要让您的类包含自定义配置信息,然后将该类序列化为XML,然后将该序列化XML转换为XML节点:是吗?
您是否可以使用XMLSerializer创建的字符串并将其包装在自己的XML标记中?
XmlSerializer xs = new XmlSerializer(typeof(MyConfig));
StringWriter xout = new StringWriter();
xs.Serialize(xout, myConfig);
XmlDocument x = new XmlDocument();
x.LoadXml("<myConfig>" + xout.ToString() + "</myConfig>");
现在x是一个XmlDocument,其中包含一个元素“&lt; myconfig&gt;”,其中包含您的序列化自定义配置。
这就是你要找的东西吗?
答案 1 :(得分:3)
它需要一些工作,但XPathNavigator路由确实有用......只记得在XmlWriter上调用.Close,.Flush()不做任何事情:
//DataContractSerializer serializer = new DataContractSerializer(typeof(foo));
XmlSerializer serializer = new XmlSerializer(typeof(foo));
XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
XmlWriter writer = nav.AppendChild();
writer.WriteStartDocument();
//serializer.WriteObject(writer, new foo { bar = 42 });
serializer.Serialize(writer, new foo { bar = 42 });
writer.WriteEndDocument();
writer.Flush();
writer.Close();
Console.WriteLine(doc.OuterXml);
答案 2 :(得分:0)
一种解决方案是将内部对象序列化为字符串,然后将字符串加载到XmlDocument中,您可以在其中找到表示数据的XmlNode并将其附加到外部对象。
XmlSerializer xser1 = new XmlSerializer(typeof(Config));
XmlSerializer xser2 = new XmlSerializer(typeof(MyConfig));
MyConfig myConfig = new MyConfig();
myConfig.data = "My special data";
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlWriter xw = new XmlTextWriter(sw);
xser2.Serialize(xw, myConfig);
XmlDocument doc = new XmlDocument();
doc.LoadXml(sb.ToString());
Config config = new Config();
config.data = "some new info";
config.element = doc.LastChild;
xser1.Serialize(fs, config);
然而,这个解决方案很麻烦,我希望有更好的方法,但它现在解决了我的问题。
现在,如果我能找到几个博客上提到的神秘的XmlNodeWriter!
答案 3 :(得分:0)
至少有一个资源指向此作为XmlNodeWriter的替代:http://msdn.microsoft.com/en-us/library/5x8bxy86.aspx。否则,您可以使用他们在GotDotNet的新MSDN代码库替代品上寻找XmlNodeWriter的表格编写MS。