如何通过调用XmlSerializer.Serialize创建一个XmlNode?

15

我正在使用一个类库,它将一些配置表示为.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 实例和一个针对内部 XmlNodeXmlNodeReader

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方法,然后再在类库配置上调用相同的方法。但是,这要求在调用Serialize后使用XmlNode表示我的数据。使用XmlSerializer将对象序列化为XmlNode的最佳方式是什么?谢谢,Kevin
顺便说一句 - 看起来Microsoft曾经提供由Chris Lovett编写的XmlNodeWriter类,但现在链接已经失效了。有人知道其他可以获取此类的位置吗?
4个回答

13

那么您需要在类中包含自定义配置信息,然后将该类序列化为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,其中包含一个元素"<myconfig>",它包含您序列化的自定义配置。

这符合您要寻找的吗?


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);

doc.DocumentElement 返回所需的 XmlNode - tm1

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就好了!


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接