En este post vamos a resolver, uno a uno, los cuatro ejercicios del examen: generación de formularios y menús con HTML/CSS, definición y validación de datos con XSD/DTD y extracción de información con XQuery. Incluimos todo el código listo para copiar y pegar.
Ejercicio 1: Formulario HTML
Generamos un formulario que incluye:
- Nombre y apellidos (texto).
- Sexo (radio botones, obligatorio).
- Fecha de nacimiento.
- Dirección (obligatoria) y teléfonos: fijo (obligatorio) y móvil (opcional).
- Checkbox de aficiones (varias opciones).
- Desplegable (
<select>
). - Área de texto para comentarios.
<form action="procesar.php" method="post">
<fieldset>
<legend>Datos personales</legend>
<label for="nombre">Nombre y Apellidos:</label>
<input type="text" id="nombre" name="nombre_apellidos" required />
<p>Sexo:</p>
<label>
<input type="radio" name="sexo" value="Hombre" required /> Hombre
</label>
<label>
<input type="radio" name="sexo" value="Mujer" required /> Mujer
</label>
<label for="nacimiento">Fecha de nacimiento:</label>
<input type="date" id="nacimiento" name="fecha_nacimiento"
min="1975-01-01" max="2005-12-31" />
<label for="direccion">Dirección:</label>
<input type="text" id="direccion" name="direccion" required />
<label for="telefono_fijo">Teléfono fijo:</label>
<input type="tel" id="telefono_fijo" name="telefono_fijo"
pattern="[0-9]{5,15}" required />
<label for="telefono_movil">Teléfono móvil:</label>
<input type="tel" id="telefono_movil" name="telefono_movil"
pattern="[0-9]{5,15}" />
<fieldset>
<legend>Aficiones</legend>
<label>
<input type="checkbox" name="aficiones[]" value="Deporte" /> Deporte
</label>
<label>
<input type="checkbox" name="aficiones[]" value="Música" /> Música
</label>
<label>
<input type="checkbox" name="aficiones[]" value="Lectura" /> Lectura
</label>
<!-- … más opciones … -->
</fieldset>
<label for="pais">País:</label>
<select id="pais" name="pais">
<option value="" disabled selected>-- Selecciona --</option>
<option value="ES">España</option>
<option value="MX">México</option>
<option value="AR">Argentina</option>
<!-- … más opciones … -->
</select>
<label for="comentarios">Comentarios:</label>
<textarea id="comentarios" name="comentarios" rows="4"></textarea>
<button type="submit">Enviar</button>
</fieldset>
</form>
Ejercicio 2: Menú desplegable con HTML/CSS
Construimos una lista anidada y con CSS desplegamos los submenús al pasar el ratón:
HTML
<nav class="menu">
<ul>
<li>Item 1</li>
<li>
Item 2
<ul class="submenu">
<li>Folder 2.1
<ul class="submenu">
<li>Sub item 2.1.1</li>
<li>Sub item 2.1.2</li>
<li>Sub item 2.1.3</li>
<li>Sub item 2.1.4</li>
</ul>
</li>
</ul>
</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</nav>
CSS
.menu ul {
list-style: none;
margin: 0;
padding: 0;
}
.menu li {
position: relative;
padding: 8px 12px;
cursor: pointer;
}
.menu .submenu {
display: none;
position: absolute;
top: 100
left: 0;
}
.menu li:hover > .submenu {
display: block;
}
.menu .submenu li:hover > .submenu {
display: block;
top: 0;
left: 100
}
Ejercicio 3: XML Schema (XSD), ejemplo XML y DTD
1. Definición de .xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="personas">
<xs:complexType>
<xs:sequence>
<xs:element name="persona" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="nombre" type="xs:string"/>
<xs:element name="apellidos" type="xs:string"/>
<xs:element name="sexo">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Hombre"/>
<xs:enumeration value="Mujer"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="nacimiento" minOccurs="0">
<xs:complexType>
<xs:attribute name="dia">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="31"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="mes">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="enero"/>
<xs:enumeration value="febrero"/>
<!-- … resto meses … -->
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="ano">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1975"/>
<xs:maxInclusive value="2005"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="direccion" type="xs:string" minOccurs="1"/>
<xs:element name="telefonoFijo" type="xs:string"/>
<xs:element name="telefonoMovil" type="xs:string"
minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="foto" type="xs:anyURI" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
2. Ejemplo de personas.xml
<?xml version="1.0" encoding="UTF-8"?>
<personas xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="personas.xsd">
<persona>
<nombre>Ana</nombre>
<apellidos>García López</apellidos>
<sexo>Mujer</sexo>
<nacimiento dia="15" mes="marzo" ano="1985"/>
<direccion>Calle Falsa 123, Madrid</direccion>
<telefonoFijo>912345678</telefonoFijo>
<telefonoMovil>612345678</telefonoMovil>
<foto>imagenes/ana.jpg</foto>
</persona>
<persona>
<nombre>Luis</nombre>
<apellidos>Pérez Ruiz</apellidos>
<sexo>Hombre</sexo>
<direccion>Av. Siempre Viva 742, Sevilla</direccion>
<telefonoFijo>954321987</telefonoFijo>
</persona>
</personas>
3. DTD equivalente (personas.dtd
)
<!ENTITY
<!ELEMENT personas (persona+) >
<!ELEMENT persona (nombre, apellidos, sexo, nacimiento?, direccion, telefonoFijo, telefonoMovil*, foto?) >
<!ELEMENT nombre
<!ELEMENT apellidos
<!ELEMENT sexo (Hombre|Mujer) >
<!ELEMENT nacimiento EMPTY >
<!ATTLIST nacimiento
dia CDATA #REQUIRED
mes (enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) #REQUIRED
ano CDATA #REQUIRED
>
<!ELEMENT direccion
<!ELEMENT telefonoFijo
<!ELEMENT telefonoMovil
<!ELEMENT foto EMPTY >
<!ATTLIST foto
src CDATA #REQUIRED
>
Ejercicio 4: Consultas XQuery
Asumimos el XML raíz <biblioteca>
y cada libro como <libro id="…">
. Aquí van las consultas:
1. Libros con <editorial>
for $b in doc("libros2.xml")//libro[editorial]
return $b
2. Títulos de libros con >1 autor
for $b in doc("libros2.xml")//libro[count(autor) > 1]
return <titulo>{ $b/titulo/text() }</titulo>
3. Títulos de libros publicados después de 2004
for $b in doc("libros2.xml")//libro[year > 2004]
return $b/titulo
4. Cada libro: título + número de autores
for $b in doc("libros2.xml")//libro
let $n := count($b/autor)
return <libro>
<titulo>{ $b/titulo/text() }</titulo>
<autores>{ $n }</autores>
</libro>
5. Libros con precio > 40
for $b in doc("libros2.xml")//libro[number(precio) > 40]
return
<resultado id="{ $b/@id }">
{ $b/titulo }
{ $b/autor }
</resultado>
6. “Bases de Datos”: todo salvo <autor>
for $b in doc("libros2.xml")//libro[titulo = "Bases de Datos"]
return
<libro id="{ $b/@id }">
{ $b/@* }
{ for $c in $b/*[name() != 'autor'] return $c }
</libro>
7. Addison-Wesley tras 2005
for $b in doc("libros2.xml")//libro[editorial = "Addison-Wesley" and year > 2005]
return $b
8. Tabla HTML: título + lista de autores
let $tabla :=
<table border="1">
<tr><th>Título</th><th>Autores</th></tr>
{
for $b in doc("libros2.xml")//libro
return
<tr>
<td>{ $b/titulo/text() }</td>
<td>{
string-join($b/autor/text(), ", ")
}</td>
</tr>
}
</table>
return $tabla
¡Listo! Con este post tienes todos los pasos y el código completo para resolver los ejercicios del examen. 🎓
