La solució de l’activitat està realitzada de dues maneres diferents. La primera amb JSTL i la segona amb JSP. Podeu baixar-vos la solució en aquest
.
Primer començareu creant un projecte amb Maven (File / New Project / Maven / Web Application). Li poseu un nom de projecte, per exemple Activitat2, i seleccioneu GlassFish com a servidor d’aplicacions.
Tot seguit copieu els dos fitxers (llegintjsp.jsp i llegintjstl.jsp) al directori webapp que podeu trobar dintre del directori src / main del projecte NetBeans. Per exemple: home / alex / NetBeansProjects / Activitat2 / src / main / webapp. Podeu esborrar el fitxer index.jsp, ja que s’ha creat automàticament quan s’ha creat el projecte.
Us apareixeran els dos fitxers al programa NetBeans. Executeu-los (botó dret del ratolí Run File), i Maven baixarà les dependències que necessiten els fitxers per funcionar.
A continuació s’explicaran les parts més importants de cadascuna de les dues solucions. Començarem explicant la solució realitzada amb JSTL.
Extracte de la solució:
<c:import var="xmltext" url="http://www.aemet.es/xml/provincias/20160323_Provincias_6908.xml"/>
<h1>Lectura de dades XML amb JSTL</h1>
<x:parse xml="${xmltext}" var="output"/>
<h2>Predicció per a la província de Barcelona:</h2>
<p>
<x:out select="$output/root/prediccion/txt_prediccion" />
</p>
<ul class="list">
<x:forEach select="$output/root/prediccion/ciudad" var="item">
<li>Ciutat: <x:out select="$item/nombre" /></li>
<ul>
<li>Màx.:<x:out select="$item/maxima" /></li>
<li>Mín.:<x:out select="$item/minima" /></li>
</ul>
</x:forEach>
</ul>
A la solució anterior accediu directament a la URL de la pàgina on es troben les dades en format XML. Si ho preferiu podeu afegir directament el fitxer XML de la següent manera:
<c:set var="xmltext">
<root id="08">
<elaborado>2016-03-23T14:01:11</elaborado>
<validez_ini>2016-03-23T00:00:00</validez_ini>
<validez_fin>2016-03-24T00:00:00</validez_fin>
<actualizacion/>
<prediccion>
<txt_prediccion>
<p>
Poco nuboso en general, salvo algunas nubes altas. Temperaturas mínimas en descenso, y sin cambios las máximas. Heladas débiles en el Prepirineo y algún punto del interior. Viento variable flojo con predominio de los oestes.
</p>
</txt_prediccion>
<ciudad>
<id>6908298</id>
<nombre>Vic</nombre>
<minima>1</minima>
<maxima>18</maxima>
</ciudad>
<ciudad>
<id>6908121</id>
<nombre>Mataró</nombre>
<minima>8</minima>
<maxima>17</maxima>
</ciudad>
<ciudad>
<id>6908102</id>
<nombre>Igualada</nombre>
<minima>4</minima>
<maxima>18</maxima>
</ciudad>
<ciudad>
<id>6908307</id>
<nombre>Vilanova i la Geltrú</nombre>
<minima>7</minima>
<maxima>20</maxima>
</ciudad>
<ciudad>
<id>6908113</id>
<nombre>Manresa</nombre>
<minima>3</minima>
<maxima>19</maxima>
</ciudad>
<ciudad>
<id>6908187</id>
<nombre>Sabadell</nombre>
<minima>5</minima>
<maxima>19</maxima>
</ciudad>
<ciudad>
<id>6908019</id>
<nombre>Barcelona</nombre>
<minima>9</minima>
<maxima>17</maxima>
</ciudad>
</prediccion>
</root>
</c:set>
Si escolliu aquesta opció heu d’eliminar la línia:
<c:import var="xmltext" url="http://www.aemet.es/xml/provincias/20160323_Provincias_6908.xml"/>
Com obteniu el fitxer XML no té importància, la qüestió és què feu una vegada el teniu. Hem de saber com està construït per poder obtenir les dades correctament, i hem de mirar la seva estructura i decidir com recórrer-la.
Per poder recórrer aquest XML heu de transformar-lo en una estructura amb nodes. Existeix una funció de JSTL que donat un string que conté un XML vàlid crea una estructura en forma d’arbre, molt semblant a l’HTML, però que conté els nodes XML de l’string. La instrucció és la següent:
<x:parse xml="${xmltext}" var="output"/>
Una vegada creat l’arbre amb tots els nodes, XML el guarda a la variable anomenada output. A partir d’ara utilitzareu aquesta variable per accedir a la informació del document XML.
Si observeu l’XML veureu que es repeteixen sempre les etiquetes ciutat amb la informació que us interessa, sempre de la mateixa manera.
Podeu utilitzar un bucle per poder obtenir la informació. En aquest cas utilitzeu un bucle de tipus foreach:
<x:forEach select="$output/root/prediccion/ciudad" var="item">
<li>Ciutat: <x:out select="$item/nombre" /></li>
<ul>
<li>Màx.:<x:out select="$item/maxima" /></li>
<li>Mín.:<x:out select="$item/minima" /></li>
</ul>
</x:forEach>
Aquest bucle accedeix al node ciutat mitjançant la variable output i donat el camí fins a arribar als nodes ciutat. Llavors, per cada node ciutat seleccioneu el nom i la temperatura màxima i la mínima. Les mostreu a l’usuari en forma de llista HTML.
A més a més, us interessa donar la descripció del temps que farà el dia de la predicció. Torneu a utilitzar l’etiqueta output per accedir al text de la predicció de la següent manera:
<x:out select="$output/root/prediccion/txt_prediccion" />
Com veieu, és molt fàcil utilitzar JSTL per tractar la informació d’un fitxer XML. Podeu veure la figura figura per comprovar el resultat de l’execució de la pàgina JSTL.
A continuació es mostrarà la solució amb JSP. Vegeu un extracte de la solució:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc
= db.
parse("http://www.aemet.es/xml/provincias/20160323_Provincias_6908.xml"); Element root
= doc.
getDocumentElement(); //root element //Obtenim tots els nodes de tipus ciutat
NodeList llistaCiutats = root.getElementsByTagName("ciudad");
//Recorrem tots els nodes ciutat, un per un
for (int i = 0; i < llistaCiutats.getLength(); i++) {
//Agafem el primer node ciutat ciutat
Node ciutat = llistaCiutats.item(i);
//Agafem tots els nodes on cadascun té les dades de la ciutat (nom, id, màxima, mínima...)
NodeList dades = ciutat.getChildNodes();
//Recorrem tots els nodes de dades
for (int j = 0; j < dades.getLength(); j++) {
//Agafem el primer node
Node n = dades.item(j);
(..mostrar informació de les ciutats..)
}
}
Com veieu, no té res a veure amb JSTL. En aquest cas hem de conèixer a la perfecció l’estructura de l’XML, ja que sou vosaltres qui ha de recórrer l’arbre creat.
Per recórrer l’arbre de nodes XML heu d’accedir a la web on es troba l’XML i convertir-lo en un arbre amb nodes XML per poder tractar amb ell. Això es fa realitzant aquestes instruccions:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc
= db.
parse("http://www.aemet.es/xml/provincias/20160323_Provincias_6908.xml");
A partir d’ara ja teniu l’arbre creat a la variable doc. Heu de jugar amb aquest arbre fins a obtenir les dades que us interessa mostrar a la pàgina web. Vegeu que les funcions que us proporciona la classe Document
de Java són molt semblants a les funcions del DOM que crea un navegador web en obtenir un HTML.
Utilitzant la variable doc accediu al node principal de l’arbre, i mitjançant aquest node podeu accedir al llistat de nodes ciutat.
Element root
= doc.
getDocumentElement(); //root element //Obtenim tots els nodes de tipus ciutat
NodeList llistaCiutats = root.getElementsByTagName("ciudad");
Per accedir al llistat de nodes ciutat observeu que s’utilitza la funció getElementsByTagName, que dóna un llistat amb tots els nodes que tenen com a nom d’etiqueta XML la paraula ciutat.
Una vegada teniu tots els nodes ciutat aneu ciutat per ciutat (node a node) per agafar els nodes fills d’una ciutat. Els nodes fills, si veieu l’XML, us donen la informació de les temperatures d’una ciutat determinada.
for (int i = 0; i < llistaCiutats.getLength(); i++) {
//Agafem el primer node ciutat ciutat
Node ciutat = llistaCiutats.item(i);
//Agafem tots els nodes on cadascun té les dades de la ciutat (nom, id, màxima, mínima...)
NodeList dades = ciutat.getChildNodes();
Ara que ja heu accedit a les dades d’una ciutat les heu de mostrar per pantalla a l’usuari.
//Si és un node buit o bé és l'identificador del node, passem al següent.
if (isTextNode(n) || n.getNodeName().equals("id")) // skip nodes
{
continue;
}
//Si és el node "nombre" posem la paraula ciutat i després el seu valor.
//A més a més, afegim un nou llistat (subllistat) (<ul>) per posar les temperatures
if (n.getNodeName().equals("nombre")) {
%>
<%="<li>Ciutat:" + n.getFirstChild().getNodeValue() + "</li><ul>"%>
<%
} else {
//És el node "mínima o màxima". Mostrem els seus noms seguit dels seus valors.
%>
<%="<li>" + n.getNodeName() + ":" + n.getFirstChild().getNodeValue() + "</li>"%>
<%
}
if (n.getNodeName().equals("maxima")) {
//Si és l'ultim node (és a dir, el node màxima) tanquem el subllistat de temperatures.
%>
<%="</ul>"%>
<%
}
Al principi feu unes petites comprovacions per tal que el node sigui el que us interessa. Per exemple, no voleu mostrar l’id d’una ciutat, i llavors compareu el nom del node amb el nom de l’etiqueta XML id; si coincideix, es descarta.
També comproveu si el nom del node correspon a l’etiqueta XML nombre. Si és així, mostreu per pantalla el nom de ciutat en comptes de nombre.
Finalment, es mostren les temperatures màximes i mínimes de la ciutat.
A la figura figura podeu veure el resultat de l’execució de la pàgina JSP.