Documentos de Académico
Documentos de Profesional
Documentos de Cultura
NET (Parte 3)
Lección 2: Serialización, tipos especializados y enlace de datos
En este ejemplo se utiliza DocumentElement como el elemento raíz y Cars para cada fila de
datos. Un nombre de elemento XML no puede contener caracteres de espacio, por lo que “Year
and Make” se convierten automáticamente a Year_x0020_and_x0020_Make.
Puede ajustar la salida XML, proporcionando un esquema XML o establecer las propiedades de
la tabla de datos y sus columnas. Para cambiar los atributos Vin, Marca y año se puede
establecer la propiedad ColumnMapping cada DataColumn de MappingType.Attribute.
La columna ”Year and Make” es una columna calculada, por lo que sus datos no necesitan ser
almacenados, para esto se debe establecer su propiedad ColumnMapping a
MappingType.Hidden.
Nombre Descripción
Element La columna se asigna a un elemento XML.
Attribute La columna se asigna a un atributo XML.
SimpleContent La columna se asigna a un nodo XmlText.
Hidden La columna se asigna a una estructura interna.
Es importante entender que la propiedad ColumnMapping sólo afecta al formato de los datos al
escribir en XML.
---------------------------------VB---------------------------------
'seteo el nombre de la tabla y la forma de mapear columnas
cars.TableName = "Auto"
cars.Columns("Vin").ColumnMapping= MappingType.Attribute
cars.Columns("Make").ColumnMapping = MappingType.Attribute
cars.Columns("Year").ColumnMapping = MappingType.Attribute
cars.Columns("Year and Make").ColumnMapping= MappingType.Hidden
---------------------------------CS---------------------------------
//seteo el nombre de la tabla y la forma de mapear columnas
car.TableName = "Auto";
car.Columns["Vin"].ColumnMapping= MappingType.Attribute;
car.Columns["Make"].ColumnMapping = MappingType.Attribute;
car.Columns["Year"].ColumnMapping = MappingType.Attribute;
car.Columns["Year and Make"].ColumnMapping= MappingType.Hidden;
--------------------------------------------------------------------
El XML quedaría de esta forma:
<xml version="1.0" standalone="yes"?>
<DocumentElement>
<Auto Vin="123456789ABCD" Make="Ford" Year="2002" />
<Auto Vin="987654321XYZ" Make="Jeep" Year="2002" />
<DocumentElement>
El XML es bastante compacto, pero los tipos de datos no se guardan y todos se consideran
string.Para almacenar el esquema XML con los datos y sus tipos, se agrega la enumeración
XmlWriteMode.WriteSchema al guardar:
---------------------------------VB---------------------------------
cars.WriteXml(desktopFileName("CarWithSchema.xml"), XmlWriteMode.Write
Schema)
---------------------------------CS---------------------------------
car.WriteXml(desktopFileName("CarWithSchema.xml"), XmlWriteMode.WriteS
chema);
--------------------------------------------------------------------
Guardándolo de esta forma el xml quedaria:
<xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns=""
xmlns:xs=http://www.w3.org/2001/XMLSchema
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet"msdata:IsDataSet="true"
msdata:MainDataTable="Auto" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Auto">
<xs:complexType>
<xs:attribute name="Vin" msdata:Caption="VIN" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="23" />
<xs:restriction>
<xs:simpleType>
<xs:attribute>
<xs:attribute name="Make" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="35" />
<xs:restriction>
<xs:simpleType>
<xs:attribute>
<xs:attribute name="Year" type="xs:int" use="required" />
<xs:attribute name="Year_x0020_and_x0020_Make"
msdata:ReadOnly="true"
msdata:Expression="Year + ' ' + Make"use="prohibited">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="70" />
<xs:restriction>
<xs:simpleType>
<xs:attribute>
<xs:complexType>
<xs:element>
<xs:choice>
<xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//Auto" />
<xs:field xpath="@Vin" />
<xs:unique>
<xs:element>
<xs:schema>
<Auto Vin="123456789ABCD" Make="Ford" Year="2002" />
<Auto Vin="987654321XYZ" Make="Jeep" Year="2002" />
<NewDataSet>
Con el esquema XML incluido, todos los tipos de datos están definidos y un
DataTable se podría cargar sin problemas desde este archivo:
---------------------------------VB---------------------------------
Dim xmlTableAs New DataTable()
xmlTable.ReadXml(desktopFileName("CarWithSchema.xml"))
---------------------------------CS---------------------------------
DataTable xmlTable = newDataTable();
xmlTable.ReadXml(desktopFileName("CarWithSchema.xml"));
--------------------------------------------------------------------
---------------------------------CS---------------------------------
//anido los datos y los atributos xml
vendorData.Relations["vendor_part"].Nested= true;
foreach (DataTable dt in vendorData.Tables)
{
foreach(DataColumn dc in dt.Columns)
{
if(dc.DataType != typeof(Guid))
dc.ColumnMapping = MappingType.Attribute;
}
}
vendorData.WriteXml(desktopFileName("Vendors1.xml"),
XmlWriteMode.IgnoreSchema);
--------------------------------------------------------------------
De esta forma quedaría el XML con las relaciones anidadas:
<xml version="1.0" standalone="yes"?>
<VendorData>
<Vendor Name="Tailspin Toys">
<Id>d012b54d-c855-4c1f-969e-74554d2cb0c7<Id>
<Part PartCode="WGT1" PartDescription="Widget 1Description"
Cost="10" RetailPrice="12.32">
<Id>167583e9-f4eb-4004-9efa-5477e0f55208<Id>
<VendorId>d012b54d-c855-4c1f-969e-74554d2cb0c7<VendorId>
<Part>
<Part PartCode="WGT2" PartDescription="Widget 2Description"
Cost="9" RetailPrice="11.32">
<Id>d3b42db7-b23f-4c33-9961-f7a325342167<Id>
<VendorId>d012b54d-c855-4c1f-969e-74554d2cb0c7<VendorId>
<Part>
<Vendor>
<VendorData>
Para poder pasar los tipos de datos se la para como parámetro XmlWriteMode.WriteSchema ,
el archivo XML resultante es mucho mas grande.
Se puede utilizar el método WriteXmlSchema del DataSet para extraer la definición de
esquema XML en un archivo separado.
---------------------------------VB---------------------------------
vendorData.WriteXmlSchema(desktopFileName("VendorSchema.xsd"))
---------------------------------CS---------------------------------
vendorData.WriteXmlSchema(desktopFileName("VendorSchema.xsd"));
--------------------------------------------------------------------
Serialización de un DataSet como un DiffGram
Un DiffGram es un documento XML que contiene todos los datos del dataset, incluida la
información DataRow original (DataRowVersion).Un DataSet se puede serializar como un
DiffGram simplemente pasando XmlWriteMode.DiffGram al método WriteXml.
---------------------------------VB---------------------------------
vendorData.WriteXml(desktopFileName("VendorSchema.xsd"),
XmlWriteMode.DiffGram)
---------------------------------CS---------------------------------
vendorData.WriteXml(desktopFileName("VendorSchema.xsd")
XmlWriteMode.DiffGram);
--------------------------------------------------------------------
Ejemplo de como se vería un XML DiffGram:
<xml version="1.0" standalone="yes"?>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<VendorData>
<Vendor diffgr:id="Vendor1" msdata:rowOrder="0" Name="Tailspin
Toys">
<Id>9e3fe885-8ffd-4c58-9cbf-a486dcbc930e<Id>
<Part diffgr:id="Part1" msdata:rowOrder="0" diffgr:hasChanges="modifie
d"
PartCode="WGT1" PartDescription="Widget 1Description"
Cost="12" RetailPrice="12.32">
<Id>4e91d3ca-a4a0-416e-ad4d-cebf047afcf4<Id>
<VendorId>9e3fe885-8ffd-4c58-9cbf-a486dcbc930e<VendorId>
<Part>
<Vendor>
<VendorData>
<diffgr:before>
<Part diffgr:id="Part1" msdata:rowOrder="0" PartCode="WGT1"
PartDescription="Widget 1
Description"Cost="10" RetailPrice="12.32">
<Id>4e91d3ca-a4a0-416e-ad4d-cebf047afcf4<Id>
<VendorId>9e3fe885-8ffd-4c58-9cbf-a486dcbc930e<VendorId>
<Part>
<Part diffgr:id="Part2" diffgr:parentId="Vendor1" msdata:rowOrder="1"
PartCode="WGT2" PartDescription="Widget 2
Description" Cost="9"
RetailPrice="11.32">
<Id>75a54b24-f8bd-4bbd-8427-20a277a44908<Id>
<VendorId>9e3fe885-8ffd-4c58-9cbf-a486dcbc930e<VendorId>
<Part>
<diffgr:before>
<diffgr:diffgram>
Deserializar DataSet a partir de XML
Un dataset se puede crear fácilmente mediante la deserialización de un archivo XML o un
stream:
---------------------------------VB---------------------------------
'lee un xml y carga el dataset
Dim vendorData As New DataSet()
vendorData.ReadXmlSchema(desktopFileName("VendorSchema.xsd"))
vendorData.ReadXml(desktopFileName("Vendors3.xml"),_
XmlReadMode.IgnoreSchema)
---------------------------------CS---------------------------------
//lee un xml y carga el dataset
DataSet vendorData = new DataSet();
vendorData.ReadXmlSchema(desktopFileName("VendorSchema.xsd"));
vendorData.ReadXml(desktopFileName("Vendors3.xml"),
XmlReadMode.IgnoreSchema);
--------------------------------------------------------------------
Nombre Descripción
Auto Predeterminado. El XML es examinado por el método ReadXml y se
selecciona el modo apropiado.
ReadSchema Lee cualquier esquema en línea y carga los datos. Si el DataSet ya contiene un
esquema, se pueden agregar al mismo las nuevas tablas, aunque se producirá
una excepción si cualquier tabla del esquema en línea ya existe en el DataSet.
IgnoreSchema Omite cualquier esquema y lee los datos del esquema del DataSetexistente. Si
los datos no coinciden con el esquema existente, se descartan
InferSchema Omite cualquier esquema, deduce el esquema a partir de los datos y los carga.
DiffGram Lee un DiffGram, aplicando los cambios del DiffGram a DataSet. La semántica
es idéntica a la de una operación Merge. Al igual que ocurre con la
operación Merge, se conservan los valores RowState.
Fragment Lee fragmentos XML, como los que se generan al ejecutar consultas en una
instancia de SQL Server. Al establecer XmlReadMode en Fragment, se lee el
espacio de nombres predeterminado como el esquema en línea.
InferTypedSchema Omite cualquier esquema, deduce el esquema con establecimiento inflexible
de tipos a partir de los datos y los carga. Si el tipo no se puede deducir de los
datos, se interpreta como datos de cadena. Si elDataSet ya contiene un
esquema, se extiende el esquema actual mediante la adición de nuevas tablas
o columnas a las tablas existentes.
---------------------------------VB--------------------------
<Serializable()>
Public Class Car
Public Property Make() As String
Public Property Model() As String
Public Property Year() As Integer
End Class
---------------------------------CS--------------------------
[Serializable]
public class Car
{
public int Year { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
-------------------------------------------------------------
Data Bindings
Para enlazar controles en una aplicación de Windows Forms, se debe establecer la propiedad
DataSource del control a un objeto que implemente la interfaz IList. Además, puede que se
tengan que establecer otras propiedades, dependiendo del tipo de control y la fuente de los
datos:
Resumen de la lección