Neste artigo vou ensinar como trabalhar com arquivos XMLs de uma forma sofisticada e de alto nível. Para melhor compreensão deste recurso recomendo a leitura dos artigos Manipulação de XML com TXMLDocument, Manipulação de XML com TXMLDocument – Parte 2 e Manipulação de XML com TXMLDocument – Parte 3. Também estou considerando que você tem uma noção básica sobre XML e XML Schema, mas caso não, recomendo as seções sobre XML e XML Schema do site w3schools.
Utilizaremos nos exemplos o delphi XE, no entanto o XML Data Bind existe desde o Delphi 6, as versões anteriores eu não conheço, assim não posso afirmar se existe ou não o recurso.
Usaremos para esse exemplo um arquivo XML que representa um pedido:
<?xml version="1.0" encoding="ISO-8859-1"?> <shiporder orderid="889923" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="shiporder.biz"> <orderperson>John Smith</orderperson> <shipto> <name>Ola Nordmann</name> <address>Langgt 23</address> <city>4000 Stavanger</city> <country>Norway</country> </shipto> <item> <title>Empire Burlesque</title> <note>Special Edition</note> <quantity>1</quantity> <price>10.90</price> </item> <item> <title>Hide your heart</title> <quantity>1</quantity> <price>9.90</price> </item> </shiporder>
shiporder | Elemento raiz que representa o pedido, ele possui o atributo orderid que possui o código do pedido |
orderperson | Pessoa que fez o pedido |
shipto |
Dados de entrega
|
item |
Dados do produto no pedido
|
Para definir a estrutura e restrições do XML temos o seguinte XML Schema que é chamado de XSD (XML Schema Definition).
<?xml version="1.0" encoding="ISO-8859-1" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:simpleType name="stringtype"> <xs:restriction base="xs:string"/> </xs:simpleType> <xs:simpleType name="inttype"> <xs:restriction base="xs:positiveInteger"/> </xs:simpleType> <xs:simpleType name="dectype"> <xs:restriction base="xs:decimal"/> </xs:simpleType> <xs:simpleType name="orderidtype"> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]{6}"/> </xs:restriction> </xs:simpleType> <xs:complexType name="shiptotype"> <xs:sequence> <xs:element name="name" type="stringtype"/> <xs:element name="address" type="stringtype"/> <xs:element name="city" type="stringtype"/> <xs:element name="country" type="stringtype"/> </xs:sequence> </xs:complexType> <xs:complexType name="itemtype"> <xs:sequence> <xs:element name="title" type="stringtype"/> <xs:element name="note" type="stringtype" minOccurs="0"/> <xs:element name="quantity" type="inttype"/> <xs:element name="price" type="dectype"/> </xs:sequence> </xs:complexType> <xs:complexType name="shipordertype"> <xs:sequence> <xs:element name="orderperson" type="stringtype"/> <xs:element name="shipto" type="shiptotype"/> <xs:element name="item" maxOccurs="unbounded" type="itemtype"/> </xs:sequence> <xs:attribute name="orderid" type="orderidtype" use="required"/> </xs:complexType> <xs:element name="shiporder" type="shipordertype"/> </xs:schema>
Importaremos o arquivo XSD usando o XMLDataBind do delphi que está em: File / New / Other / Delphi Projects / XML, para isso criemos uma nova aplicação no delphi.
Será apresentado um wizard do XML Data Bind. Informe o caminho do arquivo XSD
Nesse exemplo salvamos o arquivo XSD com a extensão .biz, pois o delphi XE não importa corretamente o arquivo se ele possuir a extensão .xsd
Ao clicar em avançar percebemos que na próxima tela foi gerada uma estrutura baseada no arquivo XSD, essas estruturas são interfaces e classes para facilitar a manipulação do XML. Nessa parte se desejar poderá fazer alterações nessas estruturas e interfaces.
Ao clicar novamente em avançar será mostrado uma outra tela com todo o código fonte que será gerado
Agora basta finalizar e salvar a unit gerada pelo wizard.
No TForm da sua aplicação coloque um TMemo, um open dialog e dois TButtons. No evento onClick de um dos TButtons coloque o seguinte código
procedure TForm1.Button1Click(Sender: TObject); var pedido :IXMLShipordertype; item :IXMLItemtype; begin //Cria uma nova instância da estrutura de classes para criar um novo XML pedido := Newshiporder(); //Informações do pedido pedido.Orderid := '123456'; pedido.Orderperson := 'Livraria X'; //Informações do destinatário do pedido pedido.Shipto.Name := 'Jocimar B. A. Huss '; pedido.Shipto.Address := 'R. Carapicuiba 23'; pedido.Shipto.City := 'Mandaguari PR'; pedido.Shipto.Country := 'Brasil'; //Inclui um novo item ao pedido< item := pedido.Item.Add; item.Title := 'Programacacao em Delphi'; item.Quantity := 4; item.Price := '102,33'; item.Note := 'Nao aborda versoes mais antigas da IDE delphi'; //Inclui um novo item ao pedido item := pedido.Item.Add; item.Title := 'Programacacao em Java - Iniciante'; item.Quantity := 1; item.Price := '140,00'; item.Note := 'Somente o basico do java'; Memo1.Text := pedido.XML; memo1.Lines.SaveToFile(ExtractFilePath(Application.ExeName) + 'shiporder.xml'); end;
No evento onClick do outro TButton coloque o seguinte código
procedure TForm1.Button2Click(Sender: TObject); var pedido :IXMLShipordertype; i :Integer; begin OpenDialog1.InitialDir := ExtractFilePath(Application.ExeName); //Pergunta qual arquivo xml deseja abrir if not OpenDialog1.Execute then exit; //Cria uma nova instância da estrutura de classes para fazermos o bind pedido := Loadshiporder(OpenDialog1.FileName); memo1.Clear; //Informações do pedido memo1.Lines.Add('[Informações do pedido]'); memo1.Lines.Add('Código do pedido: ' + pedido.Orderid) memo1.Lines.Add('Pessoa do Pedido: '+pedido.Orderperson); memo1.Lines.Add(''); memo1.Lines.Add('[Dados do destinatário do pedido]'); //Infomações do destinatário do pedido memo1.Lines.Add('Nome: ' + pedido.Shipto.Name); memo1.Lines.Add('Endereço: ' + pedido.Shipto.Address); memo1.Lines.Add('Cidade: ' + pedido.Shipto.City); memo1.Lines.Add('Pais: ' + pedido.Shipto.Country); memo1.Lines.Add(''); //Inclui um novo item ao pedido memo1.Lines.Add('[Itens do pedido]'); for i := 0 to pedido.Item.Count - 1 do begin memo1.Lines.Add('Titulo: ' + pedido.Item[i].Title); memo1.Lines.Add('Quantidade: ' + IntToStr(pedido.Item[i].Quantity)); memo1.Lines.Add('Preço: ' + pedido.Item[i].Price); memo1.Lines.Add('Observação: ' + pedido.Item[i].Note); memo1.Lines.Add(''); end; end;
Pronto, o exemplo já conseguimos gerar um XML e ler um XML gerado na estrutura definida pelo XSD de exemplo. Bom é isso aí, caso tenham dúvidas postem na seção de comentários.
Caso o XML gerado possuir acentos ou outro caractere especial, acontecerá um erro ao carrega-lo. Não pude resolver esse problema, pois não consegui informar o Encoding do XML.