单流,多个XmlWriters

时间:2010-01-27 17:17:18

标签: c# .net xml xml-serialization appdomain

是否可以拥有一个流并且有多个XmlWriter写入该流并最终得到格式良好的XML?

我有一个对象层次结构,其中每个对象都完全负责序列化自身。我最近的尝试是在最高级别创建一个流,然后向下传递该流引用,并允许每个对象创建自己的XmlWriter以将自身序列化为流。但是,这最终会在不完整的父节点中创建节点(在写入子内容之前,父元素中的start元素没有完全形成,即使是使用flush也是如此。)

有多个appdomains,因此传递XmlWriter引用将不起作用。我让每个对象返回一个字符串并将该原始XML字符串写入流中,但是一些字符串变得非常非常长(集合)。这就是为什么我决定使用一个流 - 这样每个对象可以一次写出小块,而流实例都可以序列化和MBR。

我决定不使用XmlSerializer,原因我似乎没有记录。但我会相信我早先对此的判断。

感谢任何可以让我更透彻地了解我正在使用的内容。

1 个答案:

答案 0 :(得分:2)

您可能只想将每个类的xml部分作为字符串写入流而不是使用XmlWriter。这使您可以完全控制结束标记。但我已经创建了一个似乎有效的解决方法。这允许您传递可在appdomains之间序列化的流。

首先关闭一个帮助器类来初始化新的XmlWriters并在我们传递它之前修复它。

public static class XmlWriterExt
{
    /// <summary>
    /// Make sure any previous tag is ended by writing dummy text, then backtracking the position
    /// </summary>
    public static void PrepareStream(this XmlWriter writer, Stream stream)
    {
        writer.WriteElementString("x", string.Empty);
        writer.Flush();
        stream.Position -= 5; //backtrack the dummy element
    }

    /// <summary>
    /// Get an xml writer which works on fragments and without the xml declaration
    /// </summary>
    public static XmlWriter GetWriter(Stream stream)
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.OmitXmlDeclaration = true;
        settings.ConformanceLevel = ConformanceLevel.Fragment;
        XmlWriter xmlWriter = XmlWriter.Create(stream, settings);
        return xmlWriter;
    }
}

这里有几个测试类,彼此嵌套。

class TopClass
{
    InnerClass _innerClass = new InnerClass();

    public void Serialize(Stream stream)
    {
        XmlWriter xmlWriter = XmlWriterExt.GetWriter(stream);
        xmlWriter.WriteStartElement("top");
        xmlWriter.PrepareStream(stream);
        _innerClass.Serialize(stream);
        xmlWriter.WriteEndElement();
        xmlWriter.Flush();
    }
}

class InnerClass
{
    public void Serialize(Stream stream)
    {
        XmlWriter xmlWriter = XmlWriterExt.GetWriter(stream);
        xmlWriter.WriteElementString("b", "testing");
        xmlWriter.Flush();
    }
}

测试代码

MemoryStream ms = new MemoryStream();
TopClass top = new TopClass();
top.Serialize(ms);

string result = Encoding.UTF8.GetString(ms.ToArray());

和结果

<top>
  <b>testing</b>
</top>