António Cruz

Partilha de Experiências com .NET

My Links

Blog Stats

Archives

Login

Friday, August 04, 2006 #

XML2XSD

Recentemente necessitei de uma forma de gerar um XML Schema a partir de um ficheiro de XML. A ideia é poupar as pessoas de terem que fazer os XML Schemas desde o início, principalmente quado já têm um XML de exemplo e agora só necessitam de gerar o Schema correspondente. É de facto mais fácil e rápido começar por um XML Schema gerado a partir do XML, servindo como base e dessa forma só teremos que o alterar com o que pretendemos.

Em .NET, há várias ferramentas que fazem essa tarefa, incluindo o próprio Visual Studio, o utilitário XSD.exe que vem no SDK de .NET ou até no site gotdotnet.com também existe disponível para download uma aplicação de consola chamada Microsoft XSD Inference 1.0.

No entanto, o que necessitava era uma forma de disponibilizar esta funcionalidade a qualquer pessoa, em qualquer plataforma (Linux/Perl, Windows/Java, etc), e de preferência, usando uma aplicação browser-based, de modo a não ser necessário instalar qualquer aplicação, runtime, etc.

Usando a nova classe XmlSchemaInference da versão 2.0 do .NET Framework, foi fácil implementar a dita aplicação.

Para quem estiver interessado, aqui fica o source do .aspx e do respectivo code-behind:

<%

@ Page Language="C#" ValidateRequest="false" EnableViewState="false" AutoEventWireup="true" CodeFile="XML2XSD.aspx.cs" Inherits="XML2XSD" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml">
<
head runat="server">
<title>XML2XSD</title>
<style type="text/css">
body {background-color: #eee; font: 0.8em Verdana, Arial, Helvetica;}
textarea {border: solid 1px #000;}
</style>
</
head>
<
body>
<form id="form1" runat="server">
<div>
<center>
<asp:Label ID="Message" runat="server" />
<div>Paste your XML here and click <asp:Button ID="Submit" Text="Deduce Schema(s)" runat="server" /> to generate the corresponding XML Schema(s):</div>
<p><asp:TextBox ID="XML" Rows="20" Columns="80" TextMode="MultiLine" runat="server" /></p>
<p><asp:PlaceHolder ID="XSDContent" runat="server" EnableViewState="false" /></p>
</center>
</div>
</form>
</
body>
</
html>

using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Xml.Schema;

public partial class XML2XSD : Page
{
   
protected void Page_Load(object sender, EventArgs e)
   
{
        
if (XML.Text.Length > 0)
       
{
            
using (MemoryStream inputStream = new MemoryStream(Encoding.UTF8.GetBytes(XML.Text)))
            
{
                
using (XmlReader xmlReader = XmlReader.Create(inputStream))
                {
                    
XmlSchemaInference xsdi = new XmlSchemaInference();
                    
XmlSchemaSet schemaSet = xsdi.InferSchema(xmlReader);

                     XSDContent.Controls.Clear();
                     
HtmlGenericControl textArea = null;

                    
foreach (XmlSchema schema in schemaSet.Schemas())
                    {
                        
using (MemoryStream outputStream = new MemoryStream())
                         {
                             
using (XmlTextWriter xmlWriter = new XmlTextWriter(outputStream, Encoding.UTF8))
                              {
                                   xmlWriter.Formatting =
Formatting.Indented;
                                   schema.Write(xmlWriter);
                                   outputStream.Position = 0;

                                  
using (StreamReader streamReader = new StreamReader(outputStream, true))
                                   {
                                       
textArea = new HtmlGenericControl("textarea");
                                        textArea.Attributes.Add(
"rows", "20");
                                        textArea.Attributes.Add(
"cols", "80");
                                        textArea.InnerText = streamReader.ReadToEnd();
                                        XSDContent.Controls.Add(textArea);

                                       
streamReader.Close();
                                   }

                                   xmlWriter.Close();
                               }

                               outputStream.Close();
                           }
                       }

                       xmlReader.Close();
                   }

                   inputStream.Close();
               }
           }
      }
}

 

posted @ 9:09 AM | Feedback (1)