Escrever este artigo surgiu da necessidade de um amigo através de uma conversa por Skype®.
A necessidade dele era ler o arquivo XSD e não apenas validar o XML contra o XSD.
Aproveitando o gancho, eu fiz as duas coisas. A leitura do XSD e a validação pelo XSD.
Se você não sabe o que é um XSD: http://pt.wikipedia.org/wiki/XML_Schema
Eu não vou ensinar aqui a criar o XSD, pois isso daria assunto para outro artigo. ![]()
Caso queiram aprender a criar o XSD: http://www.w3schools.com/schema/schema_intro.asp
Ok! Agora que já temos uma base e já sabemos do que se trata. Vamos ao que interessa.
Primeiramente iremos criar o nosso XSD de validação do XML.
Irei chamar de endereco.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
>
<!--definir os tipos primários do nosso xml-->
<xs:simpleType name="TUF">
<xs:annotation>
<xs:documentation>Estado para usar no endereço</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="AC"/>
<xs:enumeration value="AL"/>
<xs:enumeration value="AM"/>
<xs:enumeration value="AP"/>
<xs:enumeration value="BA"/>
<xs:enumeration value="CE"/>
<xs:enumeration value="DF"/>
<xs:enumeration value="ES"/>
<xs:enumeration value="GO"/>
<xs:enumeration value="MA"/>
<xs:enumeration value="MG"/>
<xs:enumeration value="MS"/>
<xs:enumeration value="MT"/>
<xs:enumeration value="PA"/>
<xs:enumeration value="PB"/>
<xs:enumeration value="PE"/>
<xs:enumeration value="PI"/>
<xs:enumeration value="PR"/>
<xs:enumeration value="RJ"/>
<xs:enumeration value="RN"/>
<xs:enumeration value="RO"/>
<xs:enumeration value="RR"/>
<xs:enumeration value="RS"/>
<xs:enumeration value="SC"/>
<xs:enumeration value="SE"/>
<xs:enumeration value="SP"/>
<xs:enumeration value="TO"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TCEP">
<xs:annotation>
<xs:documentation>Tipo CEP</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:pattern value="[0-9\-]{9}"/>
</xs:restriction>
</xs:simpleType>
<!--definir a estrutura do xml-->
<xs:element name="enderecos">
<xs:complexType>
<xs:sequence>
<xs:element name ="endereco" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="logradouro" type="xs:string"></xs:element>
<xs:element name ="numero" type="xs:integer"></xs:element>
<xs:element name="estado" type="TUF"></xs:element>
<xs:element name="cep" type="TCEP"></xs:element>
<xs:element name="bairro" type="xs:string"></xs:element>
<xs:element name="cidade" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Ok! Criado o nosso xsd. Iremos criar mais dois arquivos endereco_erro.xml e endereco_ok.xml. Como os próprios nomes já dizem um com erro e um sem erro, para podermos testar nosso xsd.
endereco_erro.xml
<?xml version="1.0" encoding="utf-8" ?> <enderecos> <endereco> <logradouro>rua nono NoNo no no </logradouro> <numero>123</numero> <estado>XX</estado> <cep>XXs111</cep> <bairro>NonnoNon</bairro> <cidade>Non on o nNOn</cidade> </endereco> </enderecos>
endereco_ok.xml
<?xml version="1.0" encoding="utf-8" ?> <enderecos> <endereco> <logradouro>rua nono NoNo no no </logradouro> <numero>123</numero> <estado>SP</estado> <cep>11111-111</cep> <bairro>NonnoNon</bairro> <cidade>Non on o nNOn</cidade> </endereco> </enderecos>
Ok! Já temos os nossos xml’s e o nosso xsd. Agora precisamos do nosso aplicativo para ler o xsd e validar os xmls.
Para isso crie uma aplicação console no Visual Studio e cole o código abaixo na classe program.cs
Prestem atenção nas linhas em destaque. São nelas que iremos definir o nosso evento que irá capturar o erro do XML.
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Schema;
namespace XSD_XML
{
class Program
{
static void Main(string[] args)
{
#region Ler o XSD
WriteConsole("Lendo definição do arquivo XSD");
//primeiro vamos ler nosso xsd. e ver suas definições
XmlSchema schema = XmlSchema.Read(new XmlTextReader("xsd/endereco.xsd"), null);
//lista os namespaces
XmlQualifiedName[] namespaces = schema.Namespaces.ToArray();
foreach (XmlQualifiedName item in namespaces)
Console.WriteLine(string.Format("Nome: {0} Namespace: {1}", item.Name, item.Namespace));
//lista os tipos
string[] nomeTipo = null;
foreach (object item in schema.Items)
{
nomeTipo = new string[3];
if (item is XmlSchemaSimpleType)
{
XmlSchemaSimpleType sType = item as XmlSchemaSimpleType;
nomeTipo[0] = sType.Name;
nomeTipo[1] = "SimpleType";
//lista as restrições deste tipo. Se houver
XmlSchemaSimpleTypeRestriction restriction = sType.Content as XmlSchemaSimpleTypeRestriction;
if (restriction != null)
{
foreach (XmlSchemaFacet facet in restriction.Facets)
nomeTipo[2] += facet.Value + ",";
}
Console.WriteLine(string.Format("Nome: {0} Tipo: {1} Restrição:{2} ", nomeTipo));
}
else if (item is XmlSchemaElement)
{
//tipo elemento
XmlSchemaElement eType = item as XmlSchemaElement;
nomeTipo[0] = eType.Name;
nomeTipo[1] = eType.SchemaTypeName.Name;
nomeTipo[2] = "Não Tem";
Console.WriteLine(string.Format("Nome: {0} Tipo: {1} Restrição:{2} ", nomeTipo));
//le os itens deste elemento
WriteItens(eType);
}
}
#endregion
//criar o settings
XmlReaderSettings settings = new XmlReaderSettings();
/*
* ATENÇÃO:
* Aqui iremos definir o evento que será chamado se nosso xml tiver erros
*/
settings.ValidationEventHandler += new ValidationEventHandler(validatingReader_ValidationEventHandler);
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(schema);
//abrir o xml com erro
XmlReader validatingReader = XmlReader.Create("xml/endereco_erro.xml", settings);
////validar o xml
WriteConsole("Validando o XML com erros");
while (validatingReader.Read()) { };
//xml sem erros
validatingReader = XmlReader.Create("xml/endereco_ok.xml", settings);
WriteConsole("Validando o XML sem erros");
while (validatingReader.Read()) { };
Console.ReadKey();
}
/// <summary>
/// escreve os items de um elemento
/// </summary>
/// <param name="element">elemento xml</param>
private static void WriteItens(XmlSchemaElement element)
{
System.Xml.Schema.XmlSchemaType type = element.SchemaType as System.Xml.Schema.XmlSchemaType;
if (type == null) return;
System.Xml.Schema.XmlSchemaComplexType complex = type as System.Xml.Schema.XmlSchemaComplexType;
if (complex == null) return;
System.Xml.Schema.XmlSchemaSequence sequence = complex.Particle as System.Xml.Schema.XmlSchemaSequence;
if (sequence == null) return;
WriteConsole("Linhas do tipo complexo", ConsoleColor.DarkMagenta);
foreach (XmlSchemaElement item in sequence.Items)
{
Console.WriteLine(string.Format("Nome: {0}", item.Name));
}
}
/// <summary>
/// método de validação do XML. É aqui que iremos tratar o erro do nosso XML.
/// </summary>
/// <param name="sender">objeto que chamou o método</param>
/// <param name="e">argumentos do evento</param>
static void validatingReader_ValidationEventHandler(object sender, ValidationEventArgs e)
{
WriteConsole(e.Message, ConsoleColor.Red);
}
/// <summary>
/// escreve uma linha no console
/// </summary>
/// <param name="message">mensagem</param>
/// <param name="color">cor da mensagem</param>
private static void WriteConsole(string message, ConsoleColor color)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor();
}
/// <summary>
/// Escreve uma linha no console. Cor padrão azul
/// </summary>
/// <param name="message">mensagem</param>
private static void WriteConsole(string message)
{
WriteConsole(message, ConsoleColor.Blue);
}
}
}
Link para o download do projeto de exemplo. (formato .zip Visual Studio 2010) XSD XML.zip (80)
É isso ai pessoal ![]()
Até o próximo
♦ Marcelo













'

