Compartilhar via


Sincronizar um DataSet com um XmlDataDocument

Esta seção demonstra uma etapa no processamento de uma ordem de compra, usando uma sincronização fortemente DataSet tipada com um XmlDataDocument. Os exemplos a seguir criam um DataSet com um esquema minimizado que corresponde apenas a uma parte do documento XML de origem. Os exemplos usam um XmlDataDocument para preservar a fidelidade do documento XML de origem, permitindo que ele DataSet seja usado para expor um subconjunto do documento XML.

O documento XML a seguir contém todas as informações relativas a um pedido de compra: informações do cliente, itens ordenados, informações de envio e assim por diante.

<?xml version="1.0" standalone="yes"?>
<PurchaseOrder>
  <Customers>
    <CustomerID>CHOPS</CustomerID>
    <Orders>
      <OrderID>10966</OrderID>
      <OrderDetails>
        <OrderID>10966</OrderID>
        <ProductID>37</ProductID>
        <UnitPrice>26</UnitPrice>
        <Quantity>8</Quantity>
        <Discount>0</Discount>
      </OrderDetails>
      <OrderDetails>
        <OrderID>10966</OrderID>
        <ProductID>56</ProductID>
        <UnitPrice>38</UnitPrice>
        <Quantity>12</Quantity>
        <Discount>0.15</Discount>
      </OrderDetails>
      <OrderDetails>
        <OrderID>10966</OrderID>
        <ProductID>62</ProductID>
        <UnitPrice>49.3</UnitPrice>
        <Quantity>12</Quantity>
        <Discount>0.15</Discount>
      </OrderDetails>
      <CustomerID>CHOPS</CustomerID>
      <EmployeeID>4</EmployeeID>
      <OrderDate>1998-03-20T00:00:00.0000000</OrderDate>
      <RequiredDate>1998-04-17T00:00:00.0000000</RequiredDate>
      <ShippedDate>1998-04-08T00:00:00.0000000</ShippedDate>
      <ShipVia>1</ShipVia>
      <Freight>27.19</Freight>
      <ShipName>Chop-suey Chinese</ShipName>
      <ShipAddress>Hauptstr. 31</ShipAddress>
      <ShipCity>Bern</ShipCity>
      <ShipPostalCode>3012</ShipPostalCode>
      <ShipCountryOrRegion>Switzerland</ShipCountryOrRegion>
    </Orders>
    <CompanyName>Chop-suey Chinese</CompanyName>
    <ContactName>Yang Wang</ContactName>
    <ContactTitle>Owner</ContactTitle>
    <Address>Hauptstr. 29</Address>
    <City>Bern</City>
    <PostalCode>3012</PostalCode>
    <CountryOrRegion>Switzerland</CountryOrRegion>
    <Phone>0452-076545</Phone>
  </Customers>
  <Shippers>
    <ShipperID>1</ShipperID>
    <CompanyName>Speedy Express</CompanyName>
    <Phone>(503) 555-0100</Phone>
  </Shippers>
  <Shippers>
    <ShipperID>2</ShipperID>
    <CompanyName>United Package</CompanyName>
    <Phone>(503) 555-0101</Phone>
  </Shippers>
  <Shippers>
    <ShipperID>3</ShipperID>
    <CompanyName>Federal Shipping</CompanyName>
    <Phone>(503) 555-0102</Phone>
  </Shippers>
  <Products>
    <ProductID>37</ProductID>
    <ProductName>Gravad lax</ProductName>
    <QuantityPerUnit>12 - 500 g pkgs.</QuantityPerUnit>
    <UnitsInStock>11</UnitsInStock>
    <UnitsOnOrder>50</UnitsOnOrder>
    <ReorderLevel>25</ReorderLevel>
  </Products>
  <Products>
    <ProductID>56</ProductID>
    <ProductName>Gnocchi di nonna Alice</ProductName>
    <QuantityPerUnit>24 - 250 g pkgs.</QuantityPerUnit>
    <UnitsInStock>21</UnitsInStock>
    <UnitsOnOrder>10</UnitsOnOrder>
    <ReorderLevel>30</ReorderLevel>
  </Products>
  <Products>
    <ProductID>62</ProductID>
    <ProductName>Tarte au sucre</ProductName>
    <QuantityPerUnit>48 pies</QuantityPerUnit>
    <UnitsInStock>17</UnitsInStock>
    <UnitsOnOrder>0</UnitsOnOrder>
    <ReorderLevel>0</ReorderLevel>
  </Products>
</PurchaseOrder>

Uma etapa no processamento das informações de pedido de compra contidas no documento XML anterior é que a ordem seja preenchida do inventário atual da empresa. O funcionário responsável por preencher o pedido do depósito da empresa não precisa ver todo o conteúdo da ordem de compra; eles só precisam ver as informações do produto para o pedido. Para expor apenas as informações do produto do documento XML, crie um DataSet fortemente tipado usando um esquema, escrito como um esquema XSD (linguagem de definição de esquema XML), que corresponda aos produtos e às quantidades encomendadas. Para obter mais informações sobre objetos fortemente tipados DataSet, consulte Typed DataSets.

O código a seguir mostra o esquema do qual o fortemente tipado DataSet é gerado para este exemplo.

<?xml version="1.0" standalone="yes"?>
<xs:schema id="OrderDetail" xmlns=""
                            xmlns:xs="http://www.w3.org/2001/XMLSchema"
                            xmlns:codegen="urn:schemas-microsoft-com:xml-msprop"
                            xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="OrderDetail" msdata:IsDataSet="true">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="OrderDetails" codegen:typedName="LineItem" codegen:typedPlural="LineItems">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="OrderID" type="xs:int" minOccurs="0" codegen:typedName="OrderID"/>
              <xs:element name="Quantity" type="xs:short" minOccurs="0" codegen:typedName="Quantity"/>
              <xs:element name="ProductID" type="xs:int" minOccurs="0" codegen:typedName="ProductID"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="Products" codegen:typedName="Product" codegen:typedPlural="Products">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="ProductID" type="xs:int" minOccurs="0" codegen:typedName="ProductID"/>
              <xs:element name="ProductName" type="xs:string" minOccurs="0" codegen:typedName="ProductName"/>
              <xs:element name="QuantityPerUnit" type="xs:string" minOccurs="0" codegen:typedName="QuantityPerUnit"/>
              <xs:element name="UnitsInStock" type="xs:short" minOccurs="0" codegen:typedName="UnitsInStock"/>
              <xs:element name="UnitsOnOrder" type="xs:short" minOccurs="0" codegen:typedName="UnitsOnOrder"/>
              <xs:element name="ReorderLevel" type="xs:short" minOccurs="0" codegen:typedName="ReorderLevel"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
    <xs:unique name="Constraint1">
      <xs:selector xpath=".//Products" />
      <xs:field xpath="ProductID" />
    </xs:unique>
    <xs:keyref name="Relation1" refer="Constraint1" codegen:typedChildren="GetLineItems" codegen:typedParent="Product">
      <xs:selector xpath=".//OrderDetails" />
      <xs:field xpath="ProductID" />
    </xs:keyref>
  </xs:element>
</xs:schema>

Observe que apenas as informações dos elementos OrderDetails e Products do documento XML original estão incluídas no esquema do DataSet. Sincronizar o DataSet com um XmlDataDocument garante que os elementos não incluídos no DataSet persistam no documento XML.

Com o tipo fortemente tipado DataSet gerado a partir do esquema XML (com o namespace Northwind.FillOrder), é possível expor uma parte do documento XML original, sincronizando o DataSet com o XmlDataDocument que foi carregado do documento XML de origem. O DataSet gerado do esquema contém estrutura, mas nenhum dado. Os dados são preenchidos quando você carrega o XML no XmlDataDocument. Se você tentar carregar um XmlDataDocument que foi sincronizado com um DataSet que já contém dados, uma exceção será gerada.

Depois que o DataSet (e o XmlDataDocument) tiver sido atualizado, ele XmlDataDocument poderá gravar o documento XML modificado com os elementos ignorados pelo DataSet ainda intacto, conforme mostrado abaixo. No cenário da ordem de compra, depois que os itens do pedido forem preenchidos, o documento XML modificado poderá ser passado para a próxima etapa no processo de pedido, talvez para o departamento de remessa da empresa.

Imports System
Imports System.Data
Imports System.Xml
Imports Northwind.FillOrder

Public class Sample
  Public Shared Sub Main()

    Dim orderDS As OrderDetail = New OrderDetail

    Dim xmlDocument As XmlDataDocument = New XmlDataDocument(orderDS)

    xmlDocument.Load("Order.xml")

    Dim orderItem As OrderDetail.LineItem
    Dim product As OrderDetail.Product

    For Each orderItem In orderDS.LineItems
      product = orderItem.Product

      ' Remove quantity from the current stock.
      product.UnitsInStock = CType(product.UnitsInStock - orderItem.Quantity, Short)

      ' If the remaining stock is less than the reorder level, order more.
      If ((product.UnitsInStock + product.UnitsOnOrder) < product.ReorderLevel) Then
        product.UnitsOnOrder = CType(product.UnitsOnOrder + product.ReorderLevel, Short)
      End If
    Next

    xmlDocument.Save("Order_out.xml")
  End Sub
End Class
using System;
using System.Data;
using System.Xml;
using Northwind.FillOrder;

public class Sample
{
  public static void Main()
  {
    OrderDetail orderDS = new OrderDetail();

    XmlDataDocument xmlDocument = new XmlDataDocument(orderDS);

    xmlDocument.Load("Order.xml");

    foreach (OrderDetail.LineItem orderItem in orderDS.LineItems)
    {
      OrderDetail.Product product = orderItem.Product;

      // Remove quantity from the current stock.
      product.UnitsInStock = (short)(product.UnitsInStock - orderItem.Quantity);

      // If the remaining stock is less than the reorder level, order more.
      if ((product.UnitsInStock + product.UnitsOnOrder) < product.ReorderLevel)
        product.UnitsOnOrder = (short)(product.UnitsOnOrder + product.ReorderLevel);
    }

    xmlDocument.Save("Order_out.xml");
  }
}

Consulte também