2008-09-05 23 views
10

我正在使用一个类库,它代表了它在.xml中的一些配置。使用XmlSerializer读取配置。幸运的是,表示.xml的类使用XmlAnyElement属性,在该属性下允许我为自己的目的扩展配置数据,而无需修改原始类库。如何从调用XmlSerializer.Serialize创建XmlNode?

<?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。但是,这要求在拨打Serialize之后,我的数据由XmlNode表示。使用XmlSerializer将对象序列化为XmlNode的最佳方法是什么?

感谢,

-kevin

btw--它看起来像由克里斯·洛维特写的XmlNodeWriter类是可从微软有一段时间,但现在的链路断开。有没有人知道一个替代地点获得这个类?

回答

9

因此,您需要让您的类包含自定义配置信息,然后将该类序列化为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表示包含一个元件,“<的myconfig >”,它有在它的序列化的自定义配置一个如下。

这就是你想要的吗?

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

它采取了一些工作,但XPathNavigator的路线不工作...只记得打电话.Close上的XmlWriter,.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); 
+0

`doc.DocumentElement `返回所需的`XmlNode`。 – tm1 2015-05-20 09:14:38