3.6 - Utilització des de Java
Però no hem de perdre de perspectiva que el que ens interessa és accedir des de Java als documents XML.
En principi el que podem fer és portar-nos tot el document a Java i tractar-lo com ha vam fer en el tema de fitxers: ens creem un document DOM resultat d'analitzar aquest document, i per tant ja tindrem tota l'estructura del document XML en DOM. La manera de dur tot el document és una senzilla instrucció SQL. L'única dificultat és cridar a l'analitzador (parse) tenint en compte que ara no ve d'un fitxer sinó d'un String (al que haurem convertit el que ve del resulset de la consulta).
En el següent exemple agafem el document que provenia de les comarques (num=5). Una vegada en Java traurem senzillament els noms. Ho podeu fer en un projecte nou anomenat Tema8_1, en un paquet anomenat Exemples. No us oblideu de canviar la Base de Dade, usuari i contrasenya (rxx) a la vostra:
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class PG_Prova1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException, ParserConfigurationException, SAXException, IOException {
String url = "jdbc:postgresql://89.36.214.106:5432/rxx";
String usuari = "rxx";
String password = "rxx";
Class.forName("org.postgresql.Driver");
Connection con = DriverManager.getConnection(url, usuari, password);
ResultSet rs = con.createStatement().executeQuery("SELECT doc FROM P_XML WHERE num=5");
if (rs.next()) {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(rs.getString(1))));
Element arrel = (Element) doc.getDocumentElement();
NodeList llista = arrel.getElementsByTagName("nom");
for (int i = 0; i < llista.getLength(); i++) {
Element el = (Element) llista.item(i);
System.out.println(el.getNodeName() + ' ' + el.getFirstChild().getNodeValue());
}
}
con.close();
}
}
Amb l'anterior únicament estem utilitzant la capacitat de PostgreSQL de guardar documents XML. Però podem anar més enllà. Anem a fer que treballe un poc més PostgreSQL i ens done la informació un poc més elaborada. Farem una consulta XPATH. Recordem que el resultat ve en un array de XML. Però si considerem que la consulta ja ens torna la informació final podem agafar-lo com un array de strings. Recordeu que l'array no és el normal de Java, sinó el tipus de SQL. La manera que vam fer de recórrer-lo era passar-lo a un altre ResultSet
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
Connection con = DriverManager.getConnection(url, usuari, password);
ResultSet rs = con.createStatement()
.executeQuery("SELECT xpath('//poble[nom_c=\"Plana Alta\"]/nom/text()',doc) FROM P_XML WHERE num=5");
if (rs.next()) {
System.out.println(rs.getString(1));
Array pobles = rs.getArray(1);
ResultSet rs1 = pobles.getResultSet();
while (rs1.next())
System.out.println(rs1.getString(2));
}
con.close();
}
}
Hem de ser conscients que el resultat de la funció XPATH és un array de xml. Si volem només un resultat, hem d'anar en compte, perquè serà un array amb un únic element. Per exemple, si volem l'altura de Vistabella, encara que només és un resultat, ens ve en un array:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
Connection con = DriverManager.getConnection(url, usuari, password);
ResultSet rs = con.createStatement().executeQuery(
"SELECT xpath('//poble[nom=\"Vistabella del Maestrat\"]/altura/text()',doc) FROM P_XML WHERE num=5");
if (rs.next()) {
Array poble = rs.getArray(1);
ResultSet rs1 = poble.getResultSet();
if (rs1.next())
System.out.println(rs1.getString(2));
}
con.close();
}
}
Tanmateix podem estalviar-nos el segon ResltSet, si elaborem un poc millor la consulta. Com que ja sabem que només serà un resultat, en la consulta podem agafar el primer element únicament. Mireu que estem obligats a tancar la funció entre parèntesis per a que funcione bé.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
Connection con = DriverManager.getConnection(url, usuari, password);
ResultSet rs = con.createStatement().executeQuery(
"SELECT (xpath('//poble[nom=\"Vistabella del Maestrat\"]/altura/text()',doc))[1] FROM P_XML WHERE num=5");
if (rs.next()) {
System.out.println("Altura de Vistabella: " + rs.getString(1));
}
con.close();
}
}
I treballant a la inversa, també podrem inserir les dades provinents de Java (per exemple agafant les dades des d'un fitxer) en la BD de PostgreSQL. Podreu agafar el fitxer biblioteca.xml de l'aula virtual. L'haureu de col·locar a l'arrel del projecte.
Connection con = DriverManager.getConnection(url,usuari,password);
Llicenciat sota la Llicència Creative Commons Reconeixement NoComercial CompartirIgual 2.5