B2 · DOM: crear, modificar y guardar
Bloque B06 y precondiciones de B03–B05. Los fragmentos omiten los import y el manejo de excepciones; doc es un Document vacío creado con builder.newDocument() salvo que se indique otra cosa. Cuando se pregunta por el XML resultante, interesa la estructura, no la declaración ni la indentación. Los XML se muestran indentados para leerlos mejor, pero el fichero no tiene espacios ni saltos de línea entre etiquetas salvo que el enunciado diga que la indentación es real.
Crear no es insertar
¿Qué estructura tiene el árbol al terminar?
Element raiz = doc.createElement("compania");doc.appendChild(raiz);Element emp = doc.createElement("empleado");emp.setAttribute("id", "1");- Árbol:
<compania><empleado id="1"/></compania>
empleadose ha creado, pero nunca se inserta. - Árbol:
<compania/>
Correcta: falta
raiz.appendChild(emp). - Árbol:
<empleado id="1"/>
La raíz es
compania. - Árbol:
<compania><empleado><id>1</id></empleado></compania>
Ni se inserta
empleadonisetAttributecrea hijos. - Un documento sin raíz.
companiasí se ha insertado. - Lanza
DOMExceptionporqueempno tiene padre.Se puede modificar un nodo antes de insertarlo.
Repasar: B06.1.
setAttribute
emp es un elemento ya insertado. ¿Qué produce emp.setAttribute("id", "7")?
- Un hijo
<id>7</id>dentro deemp.Un atributo no es un elemento hijo.
- El atributo
id="7"en el propio elementoemp.Correcta (B06.1).
- Un atributo
idcreado pero sin asignar.setAttributelo crea y lo asigna en un solo paso. - Un texto
7dentro deemp.No toca el contenido.
- El atributo
7="id".El primer parámetro es el nombre y el segundo el valor.
- Una
DOMExceptionsiempya tiene hijos.Los atributos son independientes de los hijos.
Repasar: B06.1.
createAttribute sin asignar
¿Cuántos atributos tiene emp al terminar?
Element emp = doc.createElement("empleado");doc.appendChild(emp);Attr a = doc.createAttribute("dni");a.setValue("123");- 1, con
dni="123".Crear el atributo no lo asigna al elemento.
- 0
Correcta: faltaría
emp.setAttributeNode(a)(o usarsetAttribute). - 1, con
dni="".No se ha asignado ningún atributo.
- 2:
dniy su valor.El valor no es otro atributo.
- Lanza
DOMExceptionensetValue.Se puede dar valor a un atributo no asignado.
- No compila:
Attrno tienesetValue.Sí lo tiene.
Repasar: B06.1.
setTextContent sobre un elemento con hijos
e es la raíz de este XML. Tras e.setTextContent("x"), ¿qué imprime e.getChildNodes().getLength()?
<e> <a/> <b/></e>- 3:
a,by el texto nuevo.setTextContentsustituye el contenido, no lo añade. - 1
Correcta: los hijos previos se eliminan y queda un único nodo de texto.
- 2: se conservan
ayb.El texto los reemplaza.
- 0
Queda el nodo de texto
x. - Lanza
DOMExceptionporqueetiene hijos elemento.No es un error; simplemente los sustituye.
- 1, y es el elemento
acon el textox.El hijo resultante es un nodo de texto.
Repasar: B06.1.
appendChild mueve
x ya es hijo de a. ¿Qué imprime?
b.appendChild(x);System.out.println(a.getChildNodes().getLength() + " " + b.getChildNodes().getLength());Antes, a tenía solo el hijo x y b no tenía hijos (sin textos de indentación).
-
1 1appendChildno hace una copia. -
0 1Correcta: el nodo se mueve de
aab. -
1 0Sí se inserta en
b. -
2 1No se duplica nada en
a. - Lanza
DOMExceptionporquexya tiene padre.Insertar un nodo ya colocado lo mueve.
-
0 0El nodo no se pierde.
Repasar: B06.1, B15.1.
Segunda raíz
¿Qué ocurre?
doc.appendChild(doc.createElement("a"));doc.appendChild(doc.createElement("b"));- El documento queda con dos raíces,
ayb.Un XML solo puede tener un elemento raíz.
-
bsustituye aacomo raíz.No hay sustitución automática.
-
bse inserta dentro dea.Se intenta insertar en el documento, no en
a. - La segunda llamada lanza
DOMException.Correcta: el documento ya tiene elemento raíz.
- El error aparece solo al transformar a fichero.
Lo detecta ya la propia inserción.
- No compila.
El problema es de ejecución.
Repasar: B06.2.
removeChild de un nieto
raiz contiene emp, y emp contiene nombre. ¿Qué ocurre con raiz.removeChild(nombre)?
- Elimina
nombredeemp.removeChildsolo elimina hijos directos del receptor. - Elimina
empy todo su contenido.No elimina un nodo distinto del indicado.
- Lanza
DOMExceptionporquenombreno es hijo directo deraiz.Correcta: lo correcto es
emp.removeChild(nombre)onombre.getParentNode().removeChild(nombre). - Devuelve
nullsin cambiar nada.No devuelve
null: lanza una excepción. - Vacía el texto de
nombre.No toca el contenido.
- No compila:
removeChildrecibe unString.Recibe un
Node.
Repasar: B06.1.
Borrar en una lista viva
a es la raíz de este XML, sin espacios entre etiquetas. ¿Cuántos b quedan?
<a> <b/> <b/> <b/></a>NodeList lista = a.getElementsByTagName("b");for (int i = 0; i < lista.getLength(); i++) { a.removeChild(lista.item(i));}- 0
La lista es viva: al borrar se desplazan los índices.
- 1
Correcta: se borra el índice 0, luego el índice 1 (que era el tercero), y el bucle termina.
- 2
Sí se borran dos.
- 3
Sí se borra alguno.
- Lanza
ConcurrentModificationException.NodeListno lanza esa excepción. - Lanza
DOMExceptionen la segunda vuelta.El nodo de la segunda vuelta sí es hijo directo.
Repasar: B05.1 (listas vivas).
Origen y destino
¿Qué línea guarda doc en empleados.xml?
-
t.transform(new DOMSource(doc), new StreamResult(new File("empleados.xml")));Correcta: primero el origen y después el destino.
-
t.transform(new StreamResult(new File("empleados.xml")), new DOMSource(doc));Origen y destino invertidos: no compila.
-
new DOMSource(doc).save("empleados.xml");DOMSourceno escribe nada; solo adapta el origen. -
doc.write(new File("empleados.xml"));Documentno tiene ese método. -
t.transform(doc, new File("empleados.xml"));transformrecibe unSourcey unResult. -
new StreamResult(new File("empleados.xml"));y nada más.Crear el destino no escribe; falta
transform.
Repasar: B06.3.
Modificar sin guardar
Se parsea datos.xml, se añade un elemento al árbol y el programa termina sin llamar a transform. ¿Qué pasa con datos.xml?
- Contiene el nuevo elemento, porque el árbol está vinculado al archivo.
El árbol es una copia en memoria.
- No cambia: hay que serializar el árbol explícitamente para guardarlo.
Correcta (B06.3).
- Se vacía, porque se abrió para escritura.
parsesolo lee. - Se guarda al llamar a
normalize().normalize()no escribe en disco. - Se guarda al cerrar el
DocumentBuilder.No hay guardado automático.
- Queda bloqueado hasta reiniciar.
No hay bloqueo.
Repasar: B06.3.
Salida a consola
¿Qué hace este código?
Transformer t = TransformerFactory.newInstance().newTransformer();t.setOutputProperty(OutputKeys.INDENT, "yes");t.transform(new DOMSource(doc), new StreamResult(System.out));- Escribe el XML en un archivo y además lo muestra por consola.
Solo hay un destino: la consola.
- Muestra el XML del árbol por la salida estándar, con indentación solicitada.
Correcta (B03.3, B06.3).
- Valida el documento y muestra los errores.
Ni
transformniINDENTvalidan. - Imprime solo el texto, sin etiquetas.
Una transformación sin hoja de estilos conserva el XML.
- Convierte el XML en CSV.
INDENTes presentación, no cambia el formato. - No compila:
StreamResultno aceptaSystem.out.Acepta un
OutputStream.
Repasar: B03.3, B06.3.
Extensión del destino
El ejemplo docente transforma un DOM a catalogo.txt con Transformer y sin hoja de estilos. ¿Qué contiene el fichero?
- Texto plano sin etiquetas, porque la extensión es
.txt.La extensión no decide el formato.
- Una lista CSV de los campos.
No hay ninguna conversión a CSV.
- El mismo documento XML serializado, con sus etiquetas.
Correcta: es una transformación de identidad.
- Nada:
Transformersolo escribe ficheros.xml.Escribe en cualquier destino.
- El árbol en formato binario.
StreamResultescribe texto. - Un objeto Java serializado.
No interviene
ObjectOutputStream.
Repasar: B02.2, B03.3.
Progreso del cuestionario
0 / 0 preguntas respondidas (0%)
0 correctas
¡Cuestionario completado!
0%
0 / 0 correctas
Tiempo: