结合XmlSerializer和XmlWriter?

时间:2012-06-04 16:25:51

标签: c#

除了我使用C#的XmlSerializer序列化到xml文件的对象列表之外,我还希望在同一个xml中存储一些更独立的元素(主要是来自文本框的字符串)。

    public static void SaveBehaviors(ObservableCollection<Param> listParams)
    {
        XmlSerializer _paramsSerializer = new XmlSerializer(listParams.GetType());
        string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        path += "\\test.xml";
        using (TextWriter writeFileStream = new StreamWriter(path))
        {
            _paramsSerializer.Serialize(writeFileStream, listParams);

            using (XmlWriter writer = XmlWriter.Create(writeFileStream))
            {
                writer.WriteStartElement("Foo"); //test entry...
                writer.WriteAttributeString("Bar", "Some & value");
                writer.WriteElementString("Nested", "data");
                writer.WriteEndElement();
            }
        }
    }

但是,由于添加了元素,反序列化“test.xml”会导致错误。我想在序列化的xml文件中写入是禁止的,应该避免吗?

3 个答案:

答案 0 :(得分:2)

没有。不要那样做。

如果您需要序列化超过ObservableCollection,则定义包含类型并序列化

public static void SaveBehaviors(ObservableCollection<Param> listParams) 
{ 
    XmlSerializer _paramsSerializer = new XmlSerializer(typeof(ContainingType)); 
    var c = new ContainingType(listParams); 
    c.ExtraInformation = whatever....; 

    string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 
    path += "\\test.xml"; 
    using (TextWriter writeFileStream = new StreamWriter(path)) 
    { 
        _paramsSerializer.Serialize(writeFileStream, c); 
    } 
} 

使用XmlSerializer。

答案 1 :(得分:0)

可以这样做,但我强烈建议不要使用流来完成它。通过在编写器中重新打开流(序列化程序将在完成后将其关闭),您可以在开始时开始,这就是您获取MalFormed xml的原因。

您可以做的是将流重新加载到XmlDocument中。这是一个可以更好地为您工作的编辑功能。

public static void SaveBehaviors(ObservableCollection<Param> listParams)
{
    XmlSerializer _paramsSerializer = new XmlSerializer(listParams.GetType());
    string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
    path += "\\test.xml";
    using (TextWriter writeFileStream = new StreamWriter(path))
    {
        _paramsSerializer.Serialize(writeFileStream, listParams);

        using (XmlDocument doc = new XmlDocument())
        {
            doc.Load(path);//load from the saved document
            XmlNode fooNode = doc.CreateElement("foo");//create node
            XmlAttribute fooAtt = doc.CreateAttribute("bar");//create attribute
            fooAtt.InnerText = "some att data";//set data
            fooNode.InnerText = "some node text";//set data
            fooNode.Attributes.Append(fooAtt);//add attribute to node
            doc.DocumentElement.AppendChild(fooNode);//add node to document
            doc.Save(path);//save the changes made
        }
    }
}

你可以为此使用XmlWriter,但危险在于确保WriteStream将数据放在正确的位置。目前,我个人对XmlWriter的了解不够。这需要相当多的实验并查看我的输出文件。使用XmlDocument提供的内置格式更容易。

答案 2 :(得分:0)

这不是禁止的,你只是在写一个带有多个根标签的非法xml文件 - 你需要在编写序列化对象之前写出一个初始元素标签,然后在写完自定义元素后关闭该标签 - 在您使用的代码模式中,您需要手动编写此标记和结束标记