C# 如何通过调用 XmlSerializer.Serialize 创建 XmlNode?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create an XmlNode from a call to XmlSerializer.Serialize?
提问by Kevin
I am using a class library which represents some of its configuration in .xml. The configuration is read in using the XmlSerializer
. Fortunately, the classes which represent the .xml use the XmlAnyElement
attribute at which allows me to extend the configuration data for my own purposes without modifying the original class library.
我正在使用一个类库,它在 .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>
This works well for deserialization. I am able to allow the class library to deserialize the .xml as normal and the I can use my own XmlSerializer
instances with a XmlNodeReader
against the internal XmlNode
.
这适用于反序列化。我能够允许类库像往常一样反序列化 .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));
}
}
}
I need to create a utility which will allow the user to generate a new configuration file that includes both the class library configuration as well my own configuration, so new objects will be created which were not read from the .xml file. The question is how can I serialize the data back into .xml?
我需要创建一个实用程序,它允许用户生成一个新的配置文件,其中包括类库配置以及我自己的配置,因此将创建不是从 .xml 文件中读取的新对象。问题是如何将数据序列化回 .xml?
I realize that I have to initially call XmlSerializer.Serialize
on my data before calling the same method on the class library configuration. However, this requires that my data is represented by an XmlNode
after calling Serialize
. What is the best way to serialize an object into an XmlNode
using the XmlSerializer
?
我意识到XmlSerializer.Serialize
在对类库配置调用相同的方法之前,我必须首先调用我的数据。但是,这要求我的数据由XmlNode
调用后的Serialize
. XmlNode
使用 将对象序列化为 的最佳方法是XmlSerializer
什么?
Thanks,
谢谢,
-kevin
-凯文
btw-- It looks like an XmlNodeWriter
class written by Chris Lovett was available at one time from Microsoft, but the links are now broken. Does anyone know of an alternative location to get this class?
顺便说一句 - 看起来XmlNodeWriter
Chris Lovett 编写的一个类曾经可以从 Microsoft 获得,但链接现在已断开。有没有人知道这个课程的替代位置?
采纳答案by Ed Schwehm
So you need to have your class contain custom configuration information, then serialize that class to XML, then make that serialized XML into an XML node: is that right?
因此,您需要让您的类包含自定义配置信息,然后将该类序列化为 XML,然后将该序列化的 XML 变成一个 XML 节点:对吗?
Could you just take the string created by the XMLSerializer and wrap that in it's own XML tags?
您能否将 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>");
Now x is an XmlDocument containing one element, "<myconfig>", which has your serialized custom configuration in it.
现在 x 是包含一个元素“<myconfig>”的 XmlDocument,其中包含您的序列化自定义配置。
Is that at all what you're looking for?
这就是你要找的吗?
回答by Kevin
One solution is to serialize the inner object to a string and then load the string into a XmlDocument where you can find the XmlNode representing your data and attach it to the outer object.
一种解决方案是将内部对象序列化为字符串,然后将该字符串加载到 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);
However, this solution is cumbersome and I would hope there is a better way, but it resolves my problem for now.
但是,这个解决方案很麻烦,我希望有更好的方法,但它暂时解决了我的问题。
Now if I could just find the mythical XmlNodeWriter referred to on several blogs!
现在,如果我能在几个博客中找到神话般的 XmlNodeWriter 就好了!
回答by Ed Schwehm
At least one resource points to this as an alternative to XmlNodeWriter: http://msdn.microsoft.com/en-us/library/5x8bxy86.aspx. Otherwise, you could write MS using that form they have on the new MSDN Code Library replacement for GotDotNet looking for XmlNodeWriter.
至少有一个资源指出这是 XmlNodeWriter 的替代方案:http: //msdn.microsoft.com/en-us/library/5x8bxy86.aspx。否则,您可以使用他们在新的 MSDN 代码库替代 GotDotNet 上寻找 XmlNodeWriter 的形式编写 MS。
回答by Ed Schwehm
It took a bit of work, but the XPathNavigator route does work... just remember to call .Close on the XmlWriter, .Flush() doesn't do anything:
这需要一些工作,但 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);