Как сериализовать XML-сериализуемый объект в XML-фрагмент (без XML-объявления или ссылок пространства имен в корневом элементе)?
Сериализация в XML-фрагмент - не XML-документ
Ответ 1
Вот хакерский способ сделать это, не загружая всю строку вывода в XmlDocument:
using System;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
public class Example
{
public String Name { get; set; }
static void Main()
{
Example example = new Example { Name = "Foo" };
XmlSerializer serializer = new XmlSerializer(typeof(Example));
XmlSerializerNamespaces emptyNamespace = new XmlSerializerNamespaces();
emptyNamespace.Add(String.Empty, String.Empty);
StringBuilder output = new StringBuilder();
XmlWriter writer = XmlWriter.Create(output,
new XmlWriterSettings { OmitXmlDeclaration = true });
serializer.Serialize(writer, example, emptyNamespace);
Console.WriteLine(output.ToString());
}
}
Ответ 2
Вы должны иметь возможность просто сериализовать, как обычно, а затем использовать свойство Root
из результирующего документа.
Возможно, вам придется сначала очистить атрибуты элемента.
Ответ 3
Кстати, это потрясающе. Я реализовал этот код, чтобы упростить работу с xml-фрагментами в виде классов, а затем вы можете просто заменить node по завершении. Это делает переход между кодом и xml ультра-легким.
Сначала создайте некоторые методы расширения.
public static class SerializableFragmentExtensions
{
public static XElement ToElement(this ISerializableFragment iSerializableFragment)
{
var serializer = new XmlSerializer(iSerializableFragment.GetType());
var emptyNamespace = new XmlSerializerNamespaces();
emptyNamespace.Add(String.Empty, String.Empty);
var output = new StringBuilder();
var writer = XmlWriter.Create(output,
new XmlWriterSettings { OmitXmlDeclaration = true });
serializer.Serialize(writer, iSerializableFragment, emptyNamespace);
return XElement.Parse(output.ToString(), LoadOptions.None);
}
public static T ToObject<T>(this XElement xElement)
{
var serializer = new XmlSerializer(typeof (T));
var reader = xElement.CreateReader();
var obj = (T) serializer.Deserialize(reader);
return obj;
}
}
Далее Внедрите требуемый интерфейс (интерфейс маркера - я знаю, что вы не должны, но я думаю, что это идеальная причина для него.)
public interface ISerializableFragment
{
}
Теперь все, что вам нужно сделать, - это украсить любой класс Serializable, который вы хотите преобразовать в фрагмент XElement с интерфейсом.
[Serializable]
public class SomeSerializableClass : ISerializableFragment
{
[XmlAttribute]
public string SomeData { get; set; }
}
Наконец, проверьте код.
static void Main(string[] args)
{
var someSerializableClassObj = new SomeSerializableClass() {SomeData = "Testing"};
var element = someSerializableClass.ToElement();
var backToSomeSerializableClassObj = element.ToObject<SomeSerializableClass>();
}
Еще раз спасибо за этот удивительно полезный код.