lunes, 29 de junio de 2009

Un editor de XML Schema gratuito... NetBeans

Cuando queremos editar un archivo XML podemos usar un editor de texto plano (aunque llega a ser confuso cuando crece mucho).

Sabemos que los XML permite cualquier estructura de datos, pero tampoco hay que abusar de ello. Es necesario que tenga un orden: cuales son los tags, cuantos, cuales y en qué orden se establecen los valores, qué atributos debe tener, etc.

Para ello se puede usar DTD, o un , XML Schema.

Usar un XML Schema tiene la gran ventaja es que es otro XML más, y que tiene más manera de restringir un XML que usando un DTD.

Para hacer un XML Schema se debería de usar un super editor de XML. El más conocido es el XML Spy. Lo he usado bastante, hasta cuando me decía que debería pagar por la versión.... además no corría en Linux.

Jugando por ahí con NetBeans encontré que también tiene su propio editor de Schemas. Y de eso lo trataré en este post.


Paso 0: Instalación del editor de XML Schemas.
Para comenzar, debemos instalar el componente, si es que no hemos instalado la opción de SOA.
Paso 1: Creando un .XSD
Nuestro .xsd resultante será el que se menciona en W3 Schools.org: XML Schema Example. Veremos que es muy sencillo.

Como nuestro NetBeans no trabaja si no es con un proyecto, crearemos uno en blanco de cualquier tipo: Desktop Application o Web Application.

Luego, crearemos un nuevo archivo (Ctrl+N), y seleccionamos de la categoría XML, el tipo de archivo "XML Schema"


.. y llamaremos a nuestro archivo "shiporder":

Al terminar, veremos que nos aparece un editor visual de XML.

En los botones superiores, podemos alternar de la vista de Esquema a Diseño (Design)

.. o a la misma fuente XML.

Regresamos al modo "Schema".

Paso 2: Definiendo los tipos simples que deberá tener el XML

Ahora, según el ejemplo descrito en el W3 Schools, el XML debe ser así:

<?xml version="1.0" encoding="ISO-8859-1"?>

<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<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>

Se puede ver a simple vista que se utilizan tres tipos de elementos simples:
  • cadena
  • entero positivo
  • decimal
Y que el ID de la orden, es una cadena que solo debe permitir 6 digitos.

Pues bien, ahora definiremos cuatro tipos de datos para nuestro esquema. Hacemos clic derecho sobre la categoría "Simple types" y seleccionamos "Add simple type..."

.. escribiremos el nombre "stringType" que será basado en el tipo "string".

... clic en OK. Repetiremos lo mismo para los siguientes tipos:
  • intType (positiveInteger)
  • decType (decimal)
  • orderIdType (string)

Paso 3: Definiendo los tipos complejos.
Los tipos complejos para el XML son para los siguientes elementos (tags):
  • shipto (name, address, city, country)
  • item (title, note, quality, price)
  • shiporder (orderperson, shipto, item)
Así que comenzaremos a crear el primer tipo complejo: shiptoType.

Clic derecho sobre "Complex types" y seleccionamos "Add Complex type..."
El nombre del tipo complejo será shiptoType, y contendrá una secuencia.

... clic en OK.

Ahora, debemos agregar la secuencia que compone ese tipo complejo. El primer subelemento es "name" de tipo "stringType". Para ello, debemos seleccionar el elemento "sequence" de "shiptoType", hacemos clic derecho, y seleccionamos "Add > Element..."


el nombre es "name" y usamos un tipo existente (el que acabamos de crear): Use existing type >Simple types > stringType
Repetiremos la acción por los otros tres subelementos más:
  • address (stringType)
  • city (stringType)
  • country (stringType)


Ahora, crearemos un nuevo tipo complejo, llamado itemType, y tendrá los siguientes subelementos:
  • title (stringType)
  • note (stringType)
  • quantity (intType)
  • price (decType)
Pero el elemento "note" es opcional. Para ello, seleccionamos clic derecho sobre ese elemento y seleccionamos "properties", y en el atributo "Min occurrs" escribimos "0"
... clic en Close.

Ahora, el tipo más complejo de todos: shiporderType. Estará compuesto de:
  • orderperson (stringType)
  • shipto (shiptoType)
  • item (itemType)
Además, debe contar con un atributo obligatorio llamado "orderid" que es de tipo "orderIdType"

Repetiremos la misma secuencia, solo que para el elemento shipto, debemos seleccionar la categoría "ComplexType > shiptoType"

.. de similar manera para item (itemType)
Ahora, este item debe permitir de uno a más elementos. Por omisión siempre permitirá unicamente un solo tag. Para esto, hacemos clic derecho sobre este elemento item recien creado, y seleccionamos "properties". Luego, cambiamos el atributo "max occurs" con el valor "unbounded".

.. clic en Close.

Ahora, debemos crear el atributo para shiporderType.Hacemos clic derecho sobre "shiporderType" y seleccionamos "Add > Attribute..."


... escribimos el nombre del atributo "orderid" de tipo "Simple Type > orderIdType"

Y este atributo, es obligatorio, por ello hacemos clic derecho sobre el atributo recién creado, seleccionamos "properties", y cambiamos el valor de "use" a "required".


.. clic en Close.

Paso 4: Creando el elemento principal
ya creados los tipos simples y complejos, debemos crear el elemento raiz de todo el XML: shiporder de tipo shiporderType.

Hacemos clic derecho sobre la categoría "Elements" y seleccionamos "Add Element"

... el nombre del elemento es "shiporder" de tipo complejo "shiporderType"



A esta altura, ya todo es tan automático y rápido que no necesita explicación.

Y listo. Podemos ver en el modo "Design" cómo ha quedado nuestro esquema.
Y si deseas, puedes ver el XML resultante.
<?xml version="1.0" encoding="UTF-8"?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xml.netbeans.org/schema/shiporder"
xmlns:tns="http://xml.netbeans.org/schema/shiporder"
elementFormDefault="qualified">
<xsd:simpleType name="intType">
<xsd:restriction base="xsd:positiveInteger"/>
</xsd:simpleType>
<xsd:simpleType name="stringType">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="decType">
<xsd:restriction base="xsd:decimal"/>
</xsd:simpleType>
<xsd:simpleType name="orderIdType">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:complexType name="shiptoType">
<xsd:sequence>
<xsd:element name="name" type="tns:stringType"></xsd:element>
<xsd:element name="address" type="tns:stringType"></xsd:element>
<xsd:element name="city" type="tns:stringType"></xsd:element>
<xsd:element name="country" type="tns:stringType"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="itemType">
<xsd:sequence>
<xsd:element name="title" type="tns:stringType"></xsd:element>
<xsd:element name="note" type="tns:stringType" minOccurs="0"></xsd:element>
<xsd:element name="quantity" type="tns:intType"></xsd:element>
<xsd:element name="price" type="tns:decType"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="shiporderType">
<xsd:sequence>
<xsd:element name="orderperson" type="tns:stringType"></xsd:element>
<xsd:element name="shipto" type="tns:shiptoType"></xsd:element>
<xsd:element name="item" type="tns:itemType" maxOccurs="unbounded"></xsd:element>
</xsd:sequence>
<xsd:attribute name="orderid" type="tns:orderIdType" use="required"/>
</xsd:complexType>
<xsd:element name="shiporder" type="tns:shiporderType"></xsd:element>
</xsd:schema>



Muy parecido al explicado en W3 Schools... y más práctico.

Paso 5: Crear un XML usando este XSD.
Crearemos un nuevo XML, pero en el tercer paso de la creación desde NetBeans, seleccionamos que use un Schema.

En el paso siguiente, hacemos clic en "browse"...

...para seleccionar el xsd que acabamos de crear.

Luego, seleccionamos cual es el esquema principal para nuestro XML (el unico) y podemos editar el prefijo (prefix) que usaremos para referirnos a ese esquema. Yo le puse "so" (ship order)



.. y para finalizar, el NetBeans nos propone crear tags en blanco usando basándose en el esquema:

.. y listo:



Un esquema de XML creado con puros clics.