Возможно, вы захотите просто записать части XML для каждого класса в виде строк в поток вместо использования XmlWriter. Это позволяет вам полностью контролировать конечные теги. Но я создал обходной путь, который, кажется, работает. Это позволяет вам передавать поток, который сериализуем между доменами приложений.
Сначала создайте вспомогательный класс для инициализации новых 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>