Как Сериализация XML знает, где поместить атрибут? - PullRequest
2 голосов
/ 24 января 2010

Я пытаюсь выяснить, как сделать сериализацию XML.

Вот как я хочу, чтобы мой XML-документ тоже выглядел в конце

<course>
    <name></name>
    <backgroundColor></backgroundColor>
    <fontColor></fontColor>
    <sharingKey></sharingKey>
    <task id="">
        <taskName></taskName>
        <description></description>
    </task>
    <task id="">
        <taskName></taskName>
        <description></description>
    </task>
</course>

Пока моя выглядит как

<?xml version="1.0" encoding="utf-8"?>
<Course xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <name>name</name>
  <backgroundColor>test</backgroundColor>
  <fontColor>test2</fontColor>
  <sharingKey>9324bfab-6cc7-49e5-84f7-56130b8dc099</sharingKey>
  <task id="first Task" />
  <task id="Second task" />
</Course>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    [XmlRoot("Course")]
    public class MyWrapper 
    {
        public MyWrapper()
        {
            TaskList = new List<Tasks>();
        }

        [XmlElement("name")]
        public string Name { get; set; }

        [XmlElement("backgroundColor")]
        public string BackgroundColor { get; set; }

        [XmlElement("fontColor")]
        public string  FontColor { get; set; }

        [XmlElement("sharingKey")]
        public Guid SharingKey { get; set; }

        [XmlElement("task")]
        public List<Tasks> TaskList { get; set; }

    }


    public class Tasks
    {
        [XmlAttribute("id")]
        public string Id { get; set; }
    }

}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            Tasks task = new Tasks();
            task.Id = "first Task";

            Tasks task2 = new Tasks();
            task2.Id = "Second task";

            MyWrapper wrap = new MyWrapper();
            wrap.BackgroundColor = "test";
            wrap.FontColor = "test2";
            wrap.Name = "name";
            wrap.SharingKey = Guid.NewGuid();

            wrap.TaskList.Add(task);
            wrap.TaskList.Add(task2);

            SerializeToXML(wrap);
        }

        static public void SerializeToXML(MyWrapper list)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));


       TextWriter textWriter = new StreamWriter(@"C:\New folder\test.xml");
        serializer.Serialize(textWriter, list);
        textWriter.Close();
    }
}

}

Итак, мой вопрос с идентификатором задачи.

Все, что у меня есть, это еще один класс с этим в нем

[XmlAttribute("id")]
public string Id { get; set; }

Как он узнал, как поместить этот атрибут в тег задачи?

Что произойдет, если я захочу получить другое свойство

[XmlElement()]
public string TaskName {get; set;}

Скажем, я хотел бы иметь атрибут с этим элементом, как бы убедиться, что атрибут будет с TaskName, а не с Task?

Ответы [ 2 ]

2 голосов
/ 24 января 2010
[XmlElement("task")]
public List<Tasks> TaskList { get; set; }

Эта часть вашего кода указала ему сериализовать каждый Tasks объект в элементе с именем "task". Сериализатор просматривает свойства класса Tasks и находит свойство Id, которое вы пометили [XmlAttribute("id")], поэтому он сериализуется как атрибут элемента "task" для объекта.

Я не уверен, что понимаю ваш второй вопрос. Вы не можете добавить атрибут к элементу, потому что его тип - строка. Вместо этого вам придется создать новый класс, чтобы обернуть понятие имени задачи, которое будет иметь свойство name и любые другие свойства, которые вы хотите добавить к нему.

0 голосов
/ 24 января 2010

В основном: XML-элементы могут иметь два вида свойств, атрибутов и элементов. Вы определили элемент XML task и атрибут на task с именем id, поэтому сериализатор добавляет атрибут к task.

Теперь предположим, что вы хотите добавить элементы, которые должны находиться в task - это тоже нормально, как я уже говорил, элементы XML могут содержать другие элементы или иметь атрибуты. Просто определите любые элементы, которые вы хотите поместить в task ... в task.

Если вы хотите, чтобы атрибут был присоединен к другому элементу, вам нужно создать новый элемент XML (здесь, соответствующий классу) и буквально установить его как тип атрибута, используя синтаксис [XmlAttribute("id")].

Возможно, здесь для вас есть несоответствие - когда вы определяете простейшую форму элемента, мы можем назвать это simpleType, и он может иметь значения, которые представляют собой Strings или Integer или любой тип относительно примитивного типа (даты действительны тоже). Но если вы хотите, чтобы тот же элемент также имел атрибуты, он внезапно должен стать complexType, так как он имеет complexContent - он может содержать как простое содержимое, так и свойства, как, скажем, атрибут.

Посмотрите, как писать XML-схемы - у w3schools есть превосходных учебных пособий - Я думаю, вы получите гораздо лучшее понимание всего этого сочетания простого и сложного контента. По сути, определяя сериализацию XML для ваших классов, вы также определяете схему XML; и вы можете скомпилировать свой код в такую ​​схему. Понимание того, как создавать схемы, позволит вам понять, как создать свой код для генерации соответствующих схем, и, кроме того, понять ваш вывод сериализации.

...