Как сериализовать объект в XML, но не должен ли он быть корневым элементом документа XML - PullRequest
2 голосов
/ 26 мая 2010

У меня есть следующий объект:

public class MyClass
{
    public int Id { get; set;}
    public string Name { get; set; }
}

Я хочу сериализовать это в следующую строку XML:

<MyClass>
    <Id>1</Id>
    <Name>My Name</Name>
</MyClass>

К сожалению, когда я использую XMLSerializer, я получаю строку, которая выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
    <Id>1</Id>
    <Name>My Name</Name>
</MyClass>

Я не хочу, чтобы MyClass был корневым элементом документа, скорее я в конечном итоге хочу добавить строку с другими подобными сериализованными объектами, которые будут в более крупном XML-документе.

т.е. В конце концов у меня будет строка XML, которая выглядит следующим образом:

<Classes>
    <MyClass>
        <Id>1</Id>
        <Name>My Name</Name>
    </MyClass>
    <MyClass>
        <Id>1</Id>
        <Name>My Name</Name>
    </MyClass>
</Classes>"

Моей первой мыслью было создать класс следующим образом:

public class Classes
{
    public List<MyClass> MyClasses { get; set; }
}

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

Мое инстинктивное чувство заключается в том, что я подхожу к этому неправильно, и что мой недостаток опыта в создании XML-файлов не помогает мне указать на какую-то часть .NET Framework или какую-то другую библиотеку, которая упрощает это. 1020 *

Ответы [ 4 ]

3 голосов
/ 26 мая 2010

Вам необходимо использовать объект XmlWriter - это дает вам полный контроль над тем, как будет отображаться XML. Вам также нужно передать экземпляр XmlSerializerNamespaces в сериализатор, чтобы получить то, что вам нужно.

Пример программы ниже дает именно то, что вы ищете (обратите внимание, как XmlWriter инициализируется с помощью XmlWriterSettings и как экземпляр XmlNamespaces передается в сериализатор):

    public class MyClass
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }


    class Program
    {
        static void Main(string[] args)
        {
            var xml = new StringBuilder();

            using (var writer = 
                XmlWriter.Create(xml, 
                        new XmlWriterSettings { Indent = true, 
                          ConformanceLevel = ConformanceLevel.Auto, 
                          OmitXmlDeclaration = true }))
            {
                MyClass myClass = new MyClass { Id = 1, Name = "My Name" };

                var ns = new XmlSerializerNamespaces();
                ns.Add("", "");

                var xs = new XmlSerializer(typeof(MyClass), "");
                xs.Serialize(writer, myClass, ns);
            }

            Console.WriteLine(xml.ToString());

            // pause program execution to review results...
            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }


//Result:
<MyClass>
<Id>1</Id>
<Name>My Name</Name>
</MyClass>
1 голос
/ 26 мая 2010

Не используйте XmlSerializer, а вместо этого используйте DataContracts. Создайте новый тип Classes, который наследует List<MyClass>, например:

[CollectionDataContract(Name = "Classes")]
public class Classes : List<MyClass>
{
}

[DataContract(Name = "MyClass")]
public class MyClass
{
    [DataMember(Name="Id")]
    public int Id { get;set; }
}

Теперь используйте DataContractSerializer для сериализации вашего Classes экземпляра:

Classes myItems = new Classes();
myItems.Add( ... );

DataContractSerializer serializer = new DataContractSerializer(typeof(Classes));
serializer.WriteObject( /* some stream */, myItems);

в ответ на комментарий

Используйте что-то вроде этого:

[CollectionDataContract(Name = "MyClasses1")]
public class MyClassesOne : List<MyClass> { }

[CollectionDataContract(Name = "MyClasses2")]
public class MyClassesTwo : List<MyClass> { }

[DataContract(Name = "Classes")]
public class Classes {
    [DataMember] public MyClassesOne MyClasses1 { get; set; }
    [DataMember] public MyClassesTwo MyClasses2 { get; set; }
}

Любой клиент может потреблять намного проще.

0 голосов
/ 26 мая 2010

Вы можете взглянуть на XStream for .NET . Этот учебник показывает, как достичь того, чего вы хотите.

0 голосов
/ 26 мая 2010

Элемент не должен быть проблемой для корневого узла. Вы можете импортировать его (это будет DocumentElement XmlDocument) в другой XmlDocument позже.

...