2010-05-04 22 views

ответ

19

Вот хак-иш способ сделать это без необходимости загружать всю выходную строку в 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()); 
    } 
} 
+0

+1 - Я не думаю, что это действительно хакерство. Возможно, больше работы, чем хотелось бы. Но, в конце концов, это говорит о том, какой формат должен быть выход, прежде чем он выполнит эту работу. Это не взломать. Взломать было бы разбить все после факта и т. Д. –

+1

Я согласен с Эндрю, что это хакерский. Если я не делаю что-то неправильно, все мои элементы имеют атрибут «xmlns =» ». Предпочитал бы, чтобы этого не было вообще. –

+0

** no XmlDocument/XmlNode манипуляции ** – Kiquenet

-2
+2

Нет. Это приведет к действительному XML-документу, который включает в себя объявление XML и ссылки на пространство имен. Я хочу только фрагмент. – Emmanuel

+0

ИМХО, лучше удалите ответ, потому что недействительны для вопроса. http://stackoverflow.com/help/how-to-answer – Kiquenet

1

Вы должны быть в состоянии только сериализации, как вы обычно делаете, а затем использовать Root свойство из полученного документа.

Возможно, вам сначала необходимо очистить атрибуты элемента.

+1

+1 Звучит неплохо для меня, но я не объяснил в своем вопросе, что я бы предпочел создать поток, а не XmlDocument. – Emmanuel

0

Кстати это является удивительным. Я реализовал этот код, чтобы упростить работу с фрагментами xml в виде классов, а затем вы можете просто заменить узел, когда закончите. Это делает переход между кодом и 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>(); 
    } 

Еще раз спасибо за этот удивительно полезный код.

+1

Была проблема, с которой я сразу попытался это сделать в своем собственном проекте. С текстовым фрагментом, который точно соответствовал правильному наименованию, как в примере, который я представил, код работал отлично. У меня было имя класса, у которого не было такого имени, как корневой элемент. Ответ заключался в простом добавлении XmlRootAttribute в класс и названии его так же, как имя корневого элемента в xml. Это работало без изъянов. Вы также можете быть уверены, что любые элементы, которые существуют в xmldocument, которые не выражены в определении класса, не нарушают разбор. – jwize

Смежные вопросы