Control de la serialización XML mediante atributos

Los atributos se pueden utilizar para controlar la serialización XML de un objeto o crear una secuencia XML alternativa a partir del mismo conjunto de clases. Para obtener más información sobre la creación de una secuencia XML alternativa, vea Cómo: Especificar un nombre de elemento alternativo para una secuencia XML.

Nota

Si el código XML generado se ajusta a la sección 5 del documento Protocolo simple de acceso a objetos (SOAP) 1.1, del Consorcio WWC (W3C), use los atributos enumerados en Atributos que controlan la serialización SOAP codificada.

La clase o nombre de miembro determina, de forma predeterminada, un nombre del elemento XML. En una clase denominada Book, un campo denominado ISBN generará una etiqueta de elemento XML <ISBN> como se muestra en el ejemplo siguiente:

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>.

Se puede cambiar este comportamiento predeterminado si desea dar un nuevo nombre al elemento. El código siguiente muestra cómo un atributo habilita esta funcionalidad estableciendo la propiedad ElementName de un XmlElementAttribute:

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

Para obtener más información sobre atributos, vea Atributos. Para obtener una lista de atributos que controlan la serialización XML, vea Atributos que controlan la serialización XML.

Controlar la serialización de la matriz

Los atributos XmlArrayAttribute y XmlArrayItemAttribute están controlan la serialización de las matrices. Con estos atributos, puede controlar el nombre de elemento, el espacio de nombres y el tipo de datos de esquemas XML (XSD) como se define en el documento W3C denominado Esquema XML Parte 2: Tipos de datos. También puede especificar los tipos que pueden estar incluidos en una matriz.

XmlArrayAttribute determinará las propiedades del elemento envolvente XML que resulta cuando se serializa una matriz. Por ejemplo, de forma predeterminada, serializar la matriz siguiente producirá un elemento XML denominado Employees. El elemento Employees contendrá una serie de elementos denominados según el tipo de matriz 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;
}

Una instancia serializada se podría parecer al siguiente código:

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

Aplicando XmlArrayAttribute, puede cambiar el nombre del elemento XML, como sigue:

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

El XML resultante puede parecerse al siguiente código:

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

XmlArrayItemAttribute, por otro lado, controla cómo se serializan los elementos contenidos en la matriz.

Nota

El atributo se aplica al campo que devuelve la matriz.

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

El XML resultante puede parecerse al siguiente código:

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

Serializar las clases derivadas

Otro uso de XmlArrayItemAttribute es permitir la serialización de clases derivadas. Por ejemplo, otra clase denominada Manager que deriva de Employee se puede agregar al ejemplo anterior. Si no aplica XmlArrayItemAttribute, se producirá un error en el código en tiempo de ejecución porque no se reconocerá el tipo de clase derivada. Para solucionar este resultado, aplique dos veces el atributo, estableciendo la propiedad Type cada vez, para cada tipo aceptable (base y derivado).

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;
}

Una instancia serializada se podría parecer al siguiente código:

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

Serializar una matriz como una secuencia de elementos

También puede serializar una matriz como una secuencia plana de elementos XML aplicando XmlElementAttribute al campo que devuelve la matriz como sigue:

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

Una instancia serializada se podría parecer al siguiente código:

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

Otra manera de diferenciar las dos secuencias XML es utilizar la herramienta de definición de esquemas XML para generar los archivos de documento de esquema XML (XSD) a partir del código compilado. Para obtener más información sobre el uso de la herramienta, vea La herramienta de definición de esquema XML y serialización XML. Cuando no se aplica ningún atributo al campo, el esquema describe el elemento de la manera siguiente:

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

Cuando XmlElementAttribute se aplica al campo, el esquema resultante describe el elemento como sigue:

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

Serializar un ArrayList

La clase ArrayList puede contener una colección de objetos diversos. Por tanto, puede utilizar un ArrayList tantas veces como utiliza la matriz. En lugar de crear un campo que devuelve una matriz de objetos escritos, sin embargo, puede crear un campo que devuelve un ArrayListúnico. Sin embargo, al igual que con las matrices, debe informar aXmlSerializer de los tipos de objetos ArrayList que contiene. Para lograr esto, asigne varias instancias de XmlElementAttribute al campo, como se muestra en el ejemplo siguiente.

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;
}

Controle la serialización de clases utilizando XmlRootAttribute y XmlTypeAttribute

Puede aplicar dos atributos solo a una clase: XmlRootAttribute y XmlTypeAttribute. Estos atributos son similares. XmlRootAttribute se puede aplicar a solo una clase: la clase que, cuando se serializa, representa el elemento de apertura y cierre del documento XML, en otras palabras, el elemento raíz. XmlTypeAttribute, por otro lado, se puede aplicar a cualquier clase, incluso a la clase raíz.

Por ejemplo, en los ejemplos anteriores, la clase Group es la clase raíz y todos sus campos públicos y propiedades se vuelven elementos XML situados en el documento XML. Además, solo puede haber una clase raíz. Aplicando XmlRootAttribute, puede controlar la secuencia XML generada por XmlSerializer. Por ejemplo, puede cambiar el nombre de elemento y espacio de nombres.

XmlTypeAttribute le permite controlar el esquema del XML generado. Esta función es útil si se necesita publicar el esquema a través de un servicio Web XML. En el siguiente ejemplo, se aplica XmlTypeAttribute y XmlRootAttribute a la misma clase:

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

Si esta clase está compilada, y la herramienta de definición de esquemas XML se utiliza para generar su esquema, encontraría el XML siguiente que describe Group:

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

En contraste, si fuera serializar una instancia de la clase, solo NewGroupName se buscarían en el documento XML:

<NewGroupName>
    . . .
</NewGroupName>

Evitar la serialización con XmlIgnoreAttribute

Es posible que se produzca una situación en la que no es necesario serializar una propiedad pública o un campo. Por ejemplo, un campo o propiedad se puede utilizar para contener los metadatos. En casos como éste, aplique XmlIgnoreAttribute al campo o la propiedad y XmlSerializer omitirán sobre él.

Vea también