[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Problem w/ Schema for elements with similar defs
- From: Eddie Robertsson <eddie@allette.com.au>
- To: José Manuel Beas <jmbeas@telenium.es>
- Date: Mon, 08 Jan 2001 17:05:52 +1100
> But this is the core of my problem. I'd like to "declare" an "object class"
> named "recurso" wich has a lot in common with "consulta". But they are not
> the same "class", "consulta" is more than "recurso". The technical problem
> arises when I am trying to say that:
>
> Recurso ::= "<recurso" AttributesOfRecurso ">" (Texto)* "</recurso>"
> Consulta ::= "<consulta" AttributesOfRecurso ">" (Texto|Imagen)*
> "</consulta>"
>
> e.g.
> <consulta nombre="C1">
> <imagen nombre="I1"/>
> <texto nombre="T1"/>
> <imagen nombre="I2"/>
> </consulta>
>
> But with the Schema mechanism "extension" like Jeff proposes I cannot write
> the former example because it is treated like:
Hi José
I think I'd better start of by saying that I've just entered the "wonderful"
world of XSD and this may not be the easiest solution but it should work for
you. I understand that you want to use the extension function due to the
similarities of the elements consulta and recurso but I agree with Henry that
it's probably better to use a the group function as suggested by Jeff. The
problem with the extension function is due to the content models of the
elements. Since the content model of recurso = texto* and the content model of
consulta = (texto | imagen)*. This means that you can't simply extend the
recurso type by adding a new element imagen. However, if you want to use the
extend function you can create a base type which only contains the common
attribute valor.
<xsd:complexType name="baseType">
<xsd:attribute name="valor"/>
</xsd:complexType>
You can then extend this baseType by adding the element texto to the recurso
type and adding a choice of the elements texto and imagen to the consulta type
(using group).
<xsd:group name="imagenOrTexto">
<xsd:choice>
<xsd:element ref="texto"/>
<xsd:element ref="imagen"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="recursoTipo">
<xsd:complexContent>
<xsd:extension base="baseType" >
<xsd:sequence>
<xsd:element ref="texto" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="consultaTipo">
<xsd:complexContent>
<xsd:extension base="baseType" >
<xsd:sequence>
<xsd:group ref="imagenOrTexto" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
You can find the complete schema at the end of the email but I don't think you
should use extension in this case. It's a complicated solution (at least the
one I came up with but maybe you can simplify it...) and I think it's much
easier to use the second solution suggested by Jeff (this schema is at the end
of the email as well).
/Eddie
XSD for the extension version:
------------------------------------------8<--------------------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsd:schema targetNamespace="http://www.telenium.es/XML"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
xmlns="http://www.telenium.es/XML" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:element name="pantallas">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="pantalla" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="pantalla">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="parametros" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="dimensiones" minOccurs="1" maxOccurs="1"/>
<!-- A reference to an abstract element that can either be consulta
or recurso -->
<xsd:element ref="consultaAndRecurso" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="nombre"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="parametros">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="parametro" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="nombre" type="xsd:string"
use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="dimensiones">
<xsd:complexType>
<xsd:attribute name="x" type="xsd:integer"/>
<xsd:attribute name="y" type="xsd:integer"/>
</xsd:complexType>
</xsd:element>
<!-- A new abstract element consultaAndRecurso is created -->
<xsd:element name="consultaAndRecurso" abstract="true" type="baseType"/>
<!-- The consulta element has the type consultaTipo and can be used as a
substitution for the abstract consultaAndRecurso element -->
<xsd:element name="consulta" type="consultaTipo"
substitutionGroup="consultaAndRecurso"/>
<!-- The recurso element has the type recursoTipo and can be used as a
substitution for the abstract consultaAndRecurso element -->
<xsd:element name="recurso" type="recursoTipo"
substitutionGroup="consultaAndRecurso"/>
<!-- The type baseType is used as base for the derivation of the two types
consultaTipo and recursoTipo. The baseType only contains the attribute valor.
-->
<xsd:complexType name="baseType">
<xsd:attribute name="valor"/>
</xsd:complexType>
<!-- A new group is created that contains either one texto element or one
imagen element -->
<xsd:group name="imagenOrTexto">
<xsd:choice>
<xsd:element ref="texto"/>
<xsd:element ref="imagen"/>
</xsd:choice>
</xsd:group>
<!-- A new type is added for the recurso element called recursoTipo. This type
extends the baseType type by adding the element texto to the content model. -->
<xsd:complexType name="recursoTipo">
<xsd:complexContent>
<xsd:extension base="baseType" >
<xsd:sequence>
<xsd:element ref="texto" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!-- A new type is created for the consulta element called consultaTipo. This
type extends the baseType type by adding the group imagenOrTexto to the content
model -->
<xsd:complexType name="consultaTipo">
<xsd:complexContent>
<xsd:extension base="baseType" >
<xsd:sequence>
<xsd:group ref="imagenOrTexto" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="texto">
<xsd:complexType>
<xsd:attributeGroup ref="componenteBasico"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="imagen">
<xsd:complexType>
<xsd:attributeGroup ref="componenteBasico"/>
<xsd:attribute name="x" type="xsd:integer"/>
<xsd:attribute name="y" type="xsd:integer"/>
</xsd:complexType>
</xsd:element>
<xsd:attributeGroup name="componenteBasico">
<xsd:attribute name="nombre" type="xsd:string"/>
<xsd:attribute name="ancho" type="xsd:integer"/>
<xsd:attribute name="alto" type="xsd:integer"/>
</xsd:attributeGroup>
</xsd:schema>
--------------------------------------------------------------------------
XSD for the second solution using groups:
------------------------------------------8<--------------------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsd:schema targetNamespace="http://www.telenium.es/XML"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
xmlns="http://www.telenium.es/XML" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:element name="pantallas">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="pantalla" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="pantalla">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="parametros" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="dimensiones" minOccurs="1" maxOccurs="1"/>
<!-- Then refer to the group and make it unbounded -->
<xsd:group ref="consultaAndRecurso" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="nombre"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="parametros">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="parametro" minOccurs="1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:attribute name="nombre" type="xsd:string"
use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="dimensiones">
<xsd:complexType>
<xsd:attribute name="x" type="xsd:integer"/>
<xsd:attribute name="y" type="xsd:integer"/>
</xsd:complexType>
</xsd:element>
<!-- A new group is created that contains either one consulta element or one
recurso element -->
<xsd:group name="consultaAndRecurso">
<xsd:choice>
<xsd:element name="consulta" type="consultaTipo" />
<xsd:element name="recurso" type="recursoTipo" />
</xsd:choice>
</xsd:group>
<!-- A new group is created that contains either one texto element or one
imagen element -->
<xsd:group name="imagenOrTexto">
<xsd:choice>
<xsd:element ref="texto"/>
<xsd:element ref="imagen"/>
</xsd:choice>
</xsd:group>
<!-- A new type is created for the recurso element called recursoTipo. -->
<xsd:complexType name="recursoTipo">
<xsd:sequence>
<xsd:element ref="texto" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="valor"/>
</xsd:complexType>
<!-- A new type is added for the consulta element called consultaTipo. -->
<xsd:complexType name="consultaTipo">
<xsd:sequence>
<xsd:group ref="imagenOrTexto" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="valor"/>
</xsd:complexType>
<xsd:element name="texto">
<xsd:complexType>
<xsd:attributeGroup ref="componenteBasico"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="imagen">
<xsd:complexType>
<xsd:attributeGroup ref="componenteBasico"/>
<xsd:attribute name="x" type="xsd:integer"/>
<xsd:attribute name="y" type="xsd:integer"/>
</xsd:complexType>
</xsd:element>
<xsd:attributeGroup name="componenteBasico">
<xsd:attribute name="nombre" type="xsd:string"/>
<xsd:attribute name="ancho" type="xsd:integer"/>
<xsd:attribute name="alto" type="xsd:integer"/>
</xsd:attributeGroup>
</xsd:schema>