B1 · DOM: parseo, árbol y extracción
Bloques B03–B05, con apoyo en B01 y B15. Los fragmentos omiten los import y el manejo de excepciones. Cuando el resultado depende de los espacios, se usa la factoría por defecto del JDK, sin validación ni opciones adicionales. 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.
Bien formado y válido
<marcas>ochenta</marcas> aparece en un XML sintácticamente correcto y no se ha configurado ningún esquema. ¿Qué hace builder.parse(...)?
- Lo rechaza porque
marcasdebería ser numérico.Sin esquema no hay tipos: el parser solo comprueba que esté bien formado.
- Lo acepta: está bien formado, y la validación contra un XSD es otra operación que habría que configurar.
Correcta (B01.2).
- Convierte
ochentaen 80.XML es texto; no hay conversión automática.
- Lanza
ParserConfigurationException.Esa excepción es de configuración del parser, no del contenido.
- Lo acepta, pero
getTextContent()devolveránull.Devuelve el texto
ochenta. - Lo valida contra el XSD que haya en la misma carpeta.
La validación nunca es automática.
Repasar: B01.2.
Crear el DocumentBuilder
¿Qué secuencia obtiene correctamente un Document a partir de clase.xml?
-
Document d = new DocumentBuilder().parse(new File("clase.xml"));DocumentBuilderes abstracta: no se instancia connew. -
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("clase.xml"))Correcta (B03.1).
-
DocumentBuilderFactory.newInstance().parse(new File("clase.xml"))La factoría crea el builder; no parsea.
-
new Document(new File("clase.xml"))Documentes una interfaz. -
DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(new File("clase.xml"))newDocument()crea un documento vacío y no recibe archivo. -
SAXParserFactory.newInstance().newDocumentBuilder().parse(...)La factoría SAX crea un
SAXParser, no unDocumentBuilder.
Repasar: B03.1.
Documento vacío
¿Qué imprime?
DocumentBuilder b = DocumentBuilderFactory.newInstance().newDocumentBuilder();Document doc = b.newDocument();System.out.println(doc.getDocumentElement());-
<root/>Java no crea una raíz por su cuenta.
-
nullCorrecta: un documento nuevo no tiene elemento raíz hasta que se añade.
-
#documentEse es el nombre del nodo documento, no su raíz.
- Lanza
SAXExceptionporque no hay XML que leer.newDocument()no lee nada. - Lanza
FileNotFoundException.No interviene ningún archivo.
- Una cadena vacía.
getDocumentElement()devuelve unElementonull.
Repasar: B03.2.
Excepciones de DOM
¿Qué combinación de excepción y momento es correcta?
-
SAXExceptional llamar anewDocumentBuilder().Al crear el builder, la excepción es
ParserConfigurationException. -
ParserConfigurationExceptional crear el builder ySAXExceptionsi el XML está mal formado al parsear.Correcta: DOM puede lanzar
SAXExceptionaunque la aplicación no use callbacks SAX. -
XMLStreamExceptional parsear con DOM.Esa excepción es de StAX.
-
JAXBExceptionsi falta el archivo.Es de JAXB; si falta el archivo, se produce una
IOException. - Ninguna:
parsedevuelvenullsi hay errores.Los errores se comunican con excepciones.
-
ClassCastExceptionsi el XML no tiene raíz.Un XML sin raíz está mal formado:
SAXException.
Repasar: B03.2.
Primer hijo con indentación
Con la factoría por defecto, se parsea este XML, cuya indentación es real (los saltos de línea y espacios están en el fichero). ¿Qué imprime?
<clase> <alumno numero="1"/></clase>Element root = doc.getDocumentElement();System.out.println(root.getFirstChild().getNodeName());-
alumnoAntes de
<alumno>hay un nodo de texto con el salto de línea y los espacios. -
#textCorrecta: el primer hijo es el texto de indentación.
-
claseEs el nombre de la raíz, no de su hijo.
-
numeroUn atributo no es un hijo ordinario.
-
nullEl método devuelve el nombre de un nodo que existe.
- Lanza
NullPointerException.getFirstChild()no esnull: hay texto.
Repasar: B04.2.
Número de hijos directos
Con la factoría por defecto, ¿qué imprime para este XML?
<a> <b/> <c/></a>System.out.println(doc.getDocumentElement().getChildNodes().getLength());- 2
Cuenta solo los elementos;
getChildNodes()incluye los textos. - 3
Cuenta un único bloque de texto.
- 5
Correcta: texto,
b, texto,c, texto. - 4
Olvida el texto que hay antes del cierre
</a>. - 1
Hay varios hijos directos.
- 0
bycson hijos directos.
Repasar: B04.2, B05.1.
Valor de un Element
e es el elemento <ciudad>Soria</ciudad>. ¿Qué imprime System.out.println(e.getNodeName() + " " + e.getNodeValue() + " " + e.getTextContent())?
-
ciudad Soria SoriagetNodeValue()de unElementesnull. -
ciudad null SoriaCorrecta (B04.3).
-
#text Soria Soria#textes el nombre de un nodo de texto, no del elemento. -
ciudad null nullgetTextContent()sí devuelve el texto descendiente. -
ciudad Soria(valor vacío)Es
null, no una cadena vacía. -
Soria null ciudadConfunde nombre y contenido.
Repasar: B04.3, B15.1.
getTextContent con subelementos
dir es el elemento siguiente, escrito en una sola línea. ¿Qué devuelve dir.getTextContent()?
<dir>Calle <num>5</num></dir>-
CalleTambién concatena el texto de los descendientes.
-
Calle <num>5</num>No devuelve marcado.
-
Calle 5Correcta: concatena todo el texto descendiente.
-
nullEso devuelve
getNodeValue(). -
5Omite el texto propio de
dir. - Lanza
DOMExceptionporque hay contenido mixto.El contenido mixto es válido.
Repasar: B04.3.
Descendientes o hijos directos
¿Qué imprime?
<grupo> <alumno/> <sub><alumno/><alumno/></sub></grupo>Element g = doc.getDocumentElement();Element sub = (Element) g.getElementsByTagName("sub").item(0);System.out.println(g.getElementsByTagName("alumno").getLength() + " " + sub.getElementsByTagName("alumno").getLength());-
1 2Desde
grupotambién encuentra los descendientes desub. -
3 2Correcta: busca en todos los descendientes del elemento receptor.
-
3 3Desde
subsolo hay dos. -
1 0Supone que solo busca hijos directos y además falla en
sub. -
2 2Cuenta mal: hay un
alumnodirecto y dos dentro desub. - Depende de la indentación.
Los espacios no son elementos
alumno.
Repasar: B05.1.
Document frente a Element
¿Qué imprime para este XML?
<item> <item/></item>System.out.println(doc.getElementsByTagName("item").getLength() + " " + doc.getDocumentElement().getElementsByTagName("item").getLength());-
1 1Desde el documento también se incluye la raíz.
-
2 1Correcta:
Documentincluye la raíz;Elementbusca solo descendientes, no a sí mismo. -
2 2El elemento receptor no se cuenta a sí mismo.
-
1 0El documento encuentra los dos.
-
0 1El documento sí encuentra coincidencias.
- Lanza excepción por repetir el nombre.
Un elemento puede contener otro con el mismo nombre.
Repasar: B05.1.
item fuera de rango
lista es un NodeList con 2 nodos. ¿Qué devuelve lista.item(2)?
- El último nodo, porque los índices empiezan en 1.
Los índices empiezan en 0: válidos 0 y 1.
-
nullCorrecta: fuera de rango devuelve
null. - Lanza
ArrayIndexOutOfBoundsException.NodeListno es un array. - Lanza
IndexOutOfBoundsException.No se lanza: devuelve
null. - El primer nodo, porque la lista es circular.
No es circular.
- Un nodo de texto vacío.
No inventa nodos.
Repasar: B05.1, B15.1.
Atributo ausente
e es <alumno numero="7"/>. ¿Qué imprime?
System.out.println("[" + e.getAttribute("curso") + "] " + e.hasAttribute("curso") + " " + (e.getAttribute("numero") + 1));-
[null] false 8En DOM, un atributo ausente da
"", y el valor es unString. -
[] false 71Correcta: cadena vacía; y
"7" + 1concatena. -
[] false 8getAttributedevuelveString:"7" + 1es"71". -
[] true 71hasAttributedistingue ausente:false. - Lanza
NullPointerException.No hay ningún
nullque se use. - No compila:
getAttributedevuelveAttr.Devuelve
String; el que devuelveAttresgetAttributeNode.
Repasar: B05.1, B05.3.
Método auxiliar sin coincidencia
alumno no contiene ningún elemento apodo. ¿Qué ocurre al llamar a getValorEtiqueta("apodo", alumno)?
public static String getValorEtiqueta(String etiqueta, Element elemento) { Node nValue = elemento.getElementsByTagName(etiqueta).item(0); return nValue.getTextContent();}- Devuelve
"".item(0)devuelvenully el método no lo comprueba. - Devuelve
null.No llega a devolver nada.
- Lanza
NullPointerExceptional llamar agetTextContent().Correcta: hay que garantizar que existe la coincidencia o comprobar
null. - Lanza
DOMExceptionengetElementsByTagName.Esa búsqueda devuelve una lista vacía sin error.
- Devuelve el texto del primer
apododel documento.Busca solo dentro de
elemento. - No compila porque
itemdevuelveElement.Devuelve
Node, que es lo que se asigna.
Repasar: B05.2.
normalize()
¿Qué hace doc.getDocumentElement().normalize()?
- Elimina toda la indentación del documento.
No elimina necesariamente texto que contiene espacios.
- Valida el XML contra su esquema.
No valida.
- Fusiona nodos de texto adyacentes y elimina los nodos de texto vacíos del subárbol.
Correcta (B04.4).
- Guarda el documento normalizado en el archivo original.
Solo cambia el árbol en memoria.
- Ordena los elementos alfabéticamente.
No reordena.
- Convierte los atributos en elementos hijos.
No cambia la estructura.
Repasar: B04.4.
Recorrer hijos de forma segura
Al recorrer root.getChildNodes(), ¿qué comprobación evita una ClassCastException al hacer (Element) n?
-
if (n != null)Los textos de indentación no son
nully tampoco sonElement. -
if (n.getNodeValue() == null)El nodo documento y otros tipos también tienen
nodeValuenulo. -
if (n.getNodeType() == Node.ELEMENT_NODE)Correcta (B04.2).
-
if (n.hasChildNodes())Un elemento vacío no tiene hijos.
-
if (n.getTextContent().isEmpty())No identifica el tipo de nodo.
- No hace falta: todos los hijos son elementos.
Puede haber texto, comentarios, etc.
Repasar: B04.2, B15.1.
Progreso del cuestionario
0 / 0 preguntas respondidas (0%)
0 correctas
¡Cuestionario completado!
0%
0 / 0 correctas
Tiempo: