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();
}
}
}
}