Управление сериализацией XML с использованием атрибутов

Атрибуты можно использовать для управления сериализацией XML объекта или для создания альтернативного потока XML из того же набора классов. Дополнительные сведения о создании альтернативного XML-потока см. в разделе "Практическое руководство. Указание альтернативного имени элемента для XML-потока".

Примечание.

Если сгенерированные XML должны удовлетворять требованиям раздела 5 Протокола SOAP 1.1 консорциума World Wide Web (W3C), используйте атрибуты, указанные в статье Атрибуты управления сериализацией с кодировкой SOAP.

По умолчанию имя элемента XML определяется классом или именем члена. В классе с именем поле с именем BookISBN создает тег <ISBN>XML-элемента, как показано в следующем примере:

Public Class Book
    Public ISBN As String
End Class
' When an instance of the Book class is serialized, it might
' produce this XML:
' <ISBN>1234567890</ISBN>.
public class Book
{
    public string ISBN;
}
// When an instance of the Book class is serialized, it might
// produce this XML:
// <ISBN>1234567890</ISBN>.

Поведение по умолчанию может быть изменено, если вы хотите присвоить элементу новое имя. В следующем коде показано, как атрибут включает эту функцию, задав ElementName свойство объекта XmlElementAttribute:

Public Class TaxRates
   < XmlElement(ElementName = "TaxRate")> _
    Public ReturnTaxRate As Decimal
End Class
public class TaxRates {
    [XmlElement(ElementName = "TaxRate")]
    public decimal ReturnTaxRate;
}

Дополнительные сведения об атрибутах см. в разделе Атрибуты. Список атрибутов, которые управляют сериализацией XML, см. в разделе Атрибуты управления сериализацией XML.

Управление сериализацией массивов

XmlArrayItemAttribute Атрибуты XmlArrayAttribute управляют сериализацией массивов. С помощью этих атрибутов вы можете управлять именем элемента, пространством имен и типом данных СХЕМЫ XML (XSD), как определено в документе W3C под названием XML Schema Part 2: Datatypes. Также можно указать типы, которые можно включить в массив.

XmlArrayAttribute определяет свойства включающего элемента XML, который создается при сериализации массива. Например, по умолчанию при сериализации массива ниже будет создан элемент XML с именем Employees. Элемент Employees будет содержать серию элементов, названную в соответствии с типом массива Employee.

Public Class Group
    Public Employees() As Employee
End Class
Public Class Employee
    Public Name As String
End Class
public class Group {
    public Employee[] Employees;
}
public class Employee {
    public string Name;
}

Сериализованный экземпляр может выглядеть следующим образом:

<Group>
<Employees>
    <Employee>
        <Name>Haley</Name>
    </Employee>
</Employees>
</Group>

Применив XmlArrayAttributeэлемент XML, можно изменить имя XML-элемента следующим образом:

Public Class Group
    <XmlArray("TeamMembers")> _
    Public Employees() As Employee
End Class
public class Group {
    [XmlArray("TeamMembers")]
    public Employee[] Employees;
}

Результирующий XML-код может выглядеть следующим образом:

<Group>
<TeamMembers>
    <Employee>
        <Name>Haley</Name>
    </Employee>
</TeamMembers>
</Group>

С другой стороны, атрибут XmlArrayItemAttribute управляет способом сериализации элементов в массиве.

Примечание.

Атрибут применяется к полю, возвращающего массив.

Public Class Group
    <XmlArrayItem("MemberName")> _
    Public Employee() As Employees
End Class
public class Group {
    [XmlArrayItem("MemberName")]
    public Employee[] Employees;
}

Результирующий XML-код может выглядеть следующим образом:

<Group>
<Employees>
    <MemberName>Haley</MemberName>
</Employees>
</Group>

Сериализация производных классов

Другим способом использования XmlArrayItemAttribute является разрешение сериализации производных классов. Например, другой класс с именем Manager, унаследованный от Employee, можно добавить в предыдущий пример. Если вы не применяете этот XmlArrayItemAttributeкод, код завершится ошибкой во время выполнения, так как производный тип класса не будет распознан. Чтобы устранить этот результат, примените атрибут дважды, каждый раз задав Type свойство для каждого допустимого типа (базовый и производный).

Public Class Group
    <XmlArrayItem(Type:=GetType(Employee)), _
    XmlArrayItem(Type:=GetType(Manager))> _
    Public Employees() As Employee
End Class
Public Class Employee
    Public Name As String
End Class
Public Class Manager
Inherits Employee
    Public Level As Integer
End Class
public class Group {
    [XmlArrayItem(Type = typeof(Employee)),
    XmlArrayItem(Type = typeof(Manager))]
    public Employee[] Employees;
}
public class Employee {
    public string Name;
}
public class Manager:Employee {
    public int Level;
}

Сериализованный экземпляр может выглядеть следующим образом:

<Group>
<Employees>
    <Employee>
        <Name>Haley</Name>
    </Employee>
    <Employee xsi:type = "Manager">
        <Name>Ann</Name>
        <Level>3</Level>
    </Employee>
</Employees>
</Group>

Сериализация массива как последовательности элементов

Можно также сериализовать массив как неструктурированную последовательность XML-элементов, применив XmlElementAttribute к полю возвращающее массив следующим образом:

Public Class Group
    <XmlElement> _
    Public Employees() As Employee
End Class
public class Group {
    [XmlElement]
    public Employee[] Employees;
}

Сериализованный экземпляр может выглядеть следующим образом:

<Group>
<Employees>
    <Name>Haley</Name>
</Employees>
<Employees>
    <Name>Noriko</Name>
</Employees>
<Employees>
    <Name>Marco</Name>
</Employees>
</Group>

Другим способом различения двух потоков XML является использование инструмента определения схемы XML, с помощью которого создаются файлы документов схемы XML (XSD) из скомпилированного кода. Дополнительные сведения об использовании средства см . в статье "Средство определения схемы XML" и сериализация XML. Если атрибут не применяется к полю, схема описывает элемент следующим образом:

<xs:element minOccurs="0" maxOccurs ="1" name="Employees" type="ArrayOfEmployee" />

XmlElementAttribute При применении к полю результирующая схема описывает элемент следующим образом:

<xs:element minOccurs="0" maxOccurs="unbounded" name="Employees" type="Employee" />

Сериализация ArrayList

Класс ArrayList может содержать коллекцию различных объектов. Таким образом, вы можете использовать многое ArrayList , как и массив. Однако вместо создания поля, возвращающего массив типизированных объектов, можно создать поле, которое возвращает один ArrayList. Но как и для массивов, XmlSerializer следует указать типы объектов, которые содержит ArrayList. Для этого необходимо назначить для поля несколько экземпляров XmlElementAttribute, как показано в следующем примере.

Public Class Group
    <XmlElement(Type:=GetType(Employee)), _
    XmlElement(Type:=GetType(Manager))> _
    Public Info As ArrayList
End Class
public class Group {
    [XmlElement(Type = typeof(Employee)),
    XmlElement(Type = typeof(Manager))]
    public ArrayList Info;
}

Управление сериализацией классов с использованием атрибутов XmlRootAttribute и XmlTypeAttribute

Можно применить два атрибута только к классу: XmlRootAttribute и XmlTypeAttribute. Эти атрибуты похожи. Атрибут XmlRootAttribute можно применить только к одному классу, классу, который при сериализации представляет открывающий и закрывающий элемент документа XML, другими словами, корневой элемент. С другой стороны, атрибут XmlTypeAttribute можно применить к любому классу, включая корневой.

В предыдущих примерах класс Group является корневым, и все его открытые поля и свойства становятся элементами XML, находящимися в документе XML. Таким образом, у вас может быть только один корневой класс. Применяя XmlRootAttribute, можно управлять потоком XML, созданным с помощью XmlSerializer. Например, можно изменить имя элемента и пространство имен.

Атрибут XmlTypeAttribute обеспечивает управление схемой созданного XML. Такая возможность полезна, когда необходимо опубликовать схему через XML-веб-службу. В следующем примере применяется как к тому же классу XmlTypeAttribute , так и XmlRootAttribute к одному и тому же классу:

<XmlRoot("NewGroupName"), _
XmlType("NewTypeName")> _
Public Class Group
    Public Employees() As Employee
End Class
[XmlRoot("NewGroupName")]
[XmlType("NewTypeName")]
public class Group {
    public Employee[] Employees;
}

Если этот класс компилируется, а средство определения схемы XML используется для создания схемы, вы найдете следующее описание XML Group:

<xs:element name="NewGroupName" type="NewTypeName" />

В отличие от этого, если нужно было сериализовать экземпляр класса, в XML-документе будет найдено только NewGroupName следующее:

<NewGroupName>
    . . .
</NewGroupName>

Предотвращение сериализации с атрибутом XmlIgnoreAttribute

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

См. также