2008-09-05 38 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