B4 · StAX: cursor e iteradores
Bloques B09–B11. Los fragmentos omiten los import y el manejo de XMLStreamException. r es un XMLStreamReader recién creado con XMLInputFactory.newInstance().createXMLStreamReader(...) sobre el XML indicado (se muestra indentado para leerlo mejor, pero el fichero no tiene espacios ni saltos de línea entre etiquetas); er es un XMLEventReader creado de la misma forma.
Pull frente a push
¿Cuál es la diferencia principal entre StAX y SAX?
- StAX construye un árbol y SAX no.
Ninguno de los dos construye un árbol completo.
- En StAX la aplicación pide el siguiente evento (pull); en SAX el parser llama al manejador (push).
Correcta (B09).
- StAX permite volver atrás en el documento.
No retrocede; como mucho se guardan eventos propios.
- SAX es pull y StAX es push.
Es al revés.
- StAX solo puede escribir XML.
Lee y escribe.
- StAX necesita JAXB para funcionar.
Es parte de
java.xml.
Repasar: B09, B15.1.
Estado inicial
Sin haber llamado a ningún otro método, ¿qué devuelve r.getEventType()?
-
START_ELEMENTde la raíz.Antes de la raíz está el inicio del documento.
-
XMLStreamConstants.START_DOCUMENTCorrecta (B10.1).
- -1, porque aún no se ha leído nada.
Siempre hay un evento actual.
-
END_DOCUMENTEse es el último.
- Lanza
IllegalStateException.Es válido consultarlo desde el principio.
-
CHARACTERSNo hay texto antes de la raíz.
Repasar: B10.1.
Recorrido de inicios
¿Qué imprime para este XML?
<a> <b/> <c>t</c></a>while (r.hasNext()) { if (r.next() == XMLStreamConstants.START_ELEMENT) { System.out.print(r.getLocalName() + " "); }}-
b cLa raíz
atambién produceSTART_ELEMENT. -
a b cCorrecta: un inicio por cada elemento, incluido el vacío.
-
a c<b/>también tiene inicio. -
a b c ttes texto, no un elemento. -
a b b c c aSolo se imprimen los inicios.
- Nada: el bucle no entra porque el estado inicial es
START_DOCUMENT.hasNext()estrueynext()avanza a la raíz.
Repasar: B10.1, B09.2.
hasNext no avanza
¿Qué imprime System.out.println(r.getEventType() == XMLStreamConstants.START_DOCUMENT) después de llamar tres veces seguidas a r.hasNext()?
-
trueCorrecta:
hasNext()comprueba sin avanzar. -
false, porque el cursor está en el tercer evento.Solo
next()avanza. -
false, porque el cursor está en la raíz.No ha avanzado nada.
- Lanza
IllegalStateException.Consultar el tipo es válido en cualquier estado.
- No compila:
hasNext()devuelveint.Devuelve
boolean. - Depende de la longitud del documento.
No avanza nunca.
Repasar: B10.1.
Dónde queda el cursor
XML, sin espacios entre etiquetas:
<libro> <t lang="en">Hola</t> <p>9</p></libro>El cursor está en el START_ELEMENT de t. ¿Qué imprime?
String texto = r.getElementText();r.next();System.out.println(texto + " " + r.getLocalName());-
Hola tgetElementText()deja el cursor en el cierre det, ynext()avanza otra vez. -
Hola pCorrecta: tras el cierre de
t, el siguiente evento es el inicio dep. -
Hola libroAntes del cierre de
libroestáp. -
t(texto vacío)El método devuelve el texto completo.
-
Holay lanzaIllegalStateExceptionengetLocalName().En un
START_ELEMENTel nombre está disponible. -
Hola 9getLocalNamedevuelve nombres de elemento.
Repasar: B10.2.
Variable de tipo desfasada
XML: <t>Hola</t>. ¿Qué imprime?
int tipo = r.next(); // START_ELEMENT de tString s = r.getElementText();System.out.println((tipo == XMLStreamConstants.START_ELEMENT) + " " + (r.getEventType() == XMLStreamConstants.END_ELEMENT));-
false trueLa variable
tipono se actualiza sola. -
true trueCorrecta:
tipoconserva el valor antiguo, pero el lector ya está en el cierre. -
true falsegetElementText()sí avanza el lector. -
false falsetiposigue valiendoSTART_ELEMENT. - Lanza
XMLStreamException.tsolo contiene texto. - No compila:
next()devuelveXMLEvent.En el cursor devuelve
int.
Repasar: B10.2.
getElementText con un subelemento
El cursor está en el inicio de nombre en este XML, con contenido mixto (por eso va en una sola línea). ¿Qué ocurre con r.getElementText()?
<nombre>Lu<b>is</b></nombre>- Devuelve
Luis.Eso haría
getTextContent()en DOM. - Devuelve
Lu.No se detiene en el subelemento devolviendo lo parcial.
- Lanza
XMLStreamException, porque el elemento no es solo texto.Correcta (B10.2).
- Devuelve
Lu<b>is</b>.Nunca devuelve marcado.
- Devuelve
null.No devuelve
null. - Devuelve
is.No salta al subelemento.
Repasar: B10.2, B14.2.
Elemento vacío
El cursor está en el inicio de <title/>. ¿Qué devuelve r.getElementText()?
-
nullDevuelve una cadena.
-
""(cadena vacía)Correcta (B10.2).
-
"title"No devuelve el nombre.
- Lanza
XMLStreamException.Un elemento vacío es de solo texto (sin texto).
- Lanza
IllegalStateException.Está en
START_ELEMENT, que es la precondición. - El texto del elemento siguiente.
No sale del elemento.
Repasar: B10.2.
Atributos según el estado
XML: <t lang="en">Hola</t>. ¿Qué imprime?
r.next(); // START_ELEMENT de tSystem.out.print(r.getAttributeValue(null, "lang") + " " + r.getAttributeValue(null, "color") + " ");r.next(); // CHARACTERSSystem.out.println(r.getAttributeValue(null, "lang"));-
en en(vacío en medio)Un atributo ausente da
null, y enCHARACTERSno se pueden consultar atributos. -
en null enEn el evento de texto ya no hay atributos que consultar.
-
en nully después lanzaIllegalStateException.Correcta: los atributos solo se consultan en
START_ELEMENT. -
null null nullEn el inicio de
tel atributo existe. - Lanza
IllegalArgumentExceptionpor elnulldel primer parámetro.nullcomo URI significa no comprobar el espacio de nombres. -
eny despuésnull.Ni el ausente es vacío ni el tercero devuelve
null.
Repasar: B10.1.
Avanzar después del final
r ya está en END_DOCUMENT y r.hasNext() es false. ¿Qué ocurre con r.next()?
- Devuelve -1.
No hay valor centinela.
- Vuelve a
START_DOCUMENT.StAX no rebobina.
- Lanza una excepción (
NoSuchElementExceptionen el JDK) porque no hay más eventos.Correcta (B10.1).
- Devuelve
END_DOCUMENTotra vez.No repite eventos.
- Devuelve
null.Devuelve un
int; no puede sernull. - Cierra el flujo de entrada.
No cierra nada.
Repasar: B10.1.
next y nextEvent
¿Qué línea no compila?
-
int tipo = r.next();Correcta en el cursor: devuelve
int. -
XMLEvent e = er.nextEvent();Correcta en la API de eventos.
-
XMLEvent e = r.next();Esta no compila: en el cursor
next()devuelve unint, no unXMLEvent. -
boolean b = er.hasNext();hasNext()existe y devuelveboolean. -
XMLEvent e = er.peek();peek()devuelve el próximoXMLEventsin consumirlo. -
int t = r.getEventType();Devuelve
int.
Repasar: B09.1, B11.2.
peek no consume
XML: <a/>. Tras consumir con er.nextEvent() el START_DOCUMENT, ¿qué imprime?
XMLEvent e1 = er.peek();XMLEvent e2 = er.nextEvent();System.out.println(e1.isStartElement() + " " + e2.isStartElement());-
true falsepeek()no consume:nextEvent()devuelve el mismo evento. -
true trueCorrecta: los dos corresponden al inicio de
a. -
false truepeek()ya muestra el inicio dea. -
false falseEl siguiente evento es el inicio de
a. - Lanza
IllegalStateExceptionenpeek().peek()es válido. - No compila:
peek()devuelveint.En
XMLEventReaderdevuelveXMLEvent.
Repasar: B11.2.
El evento guardado no cambia
ev es el StartElement de <t>Hola</t> obtenido con er.nextEvent(). Después se llama a er.getElementText(). ¿Qué afirmación es correcta?
-
evpasa a ser el evento de cierre det.El objeto obtenido antes no se transforma.
-
ev.isStartElement()sigue siendotrue: el lector avanzó, pero el objeto guardado no cambia.Correcta (B11.2).
-
evqueda anull.La variable no se modifica.
-
getElementText()no se puede usar en la API de eventos.XMLEventReadertambién tienegetElementText(). -
ev.asStartElement()avanza al siguiente evento.Solo da la vista tipada, sin consumir.
- El lector vuelve al inicio de
t.No retrocede.
Repasar: B11.1, B11.2.
Atributos en la API de eventos
¿Qué devuelve start.getAttributes() sobre un StartElement?
- Un
NodeList.NodeListes de DOM. - Un
NamedNodeMap.También es de DOM.
- Un
Iterator<Attribute>; cadaAttributetienegetName()(QName) ygetValue().Correcta (B11.1).
- Un
String[]con los valores.Devuelve objetos
Attribute. - Un evento
ATTRIBUTEque hay que consumir connextEvent().Los atributos van asociados al inicio del elemento.
- Los atributos en el orden semántico fijado por el XML.
El orden de los atributos no tiene significado en XML.
Repasar: B11.1, B09.2.
Cerrar el lector
¿Por qué no compila este código en JDK 17?
try (XMLStreamReader r = XMLInputFactory.newInstance() .createXMLStreamReader(new FileInputStream("a.xml"))) { // …}- Porque
createXMLStreamReaderno admite unInputStream.Sí lo admite.
- Porque
XMLStreamReaderno implementaAutoCloseable, así que no puede ir en untry-with-resources.Correcta: se cierra en un
finally, y el flujo de origen sí en eltry-with-resources. - Porque
XMLStreamReaderno tiene métodoclose().Lo tiene, pero no implementa
AutoCloseable. - Porque falta capturar
SAXException.StAX usa
XMLStreamException. - Porque
XMLInputFactoryno tienenewInstance().Sí lo tiene.
- Sí compila; solo avisa de un recurso sin cerrar.
Es un error de compilación.
Repasar: B11.3.
Progreso del cuestionario
0 / 0 preguntas respondidas (0%)
0 correctas
¡Cuestionario completado!
0%
0 / 0 correctas
Tiempo: