Projecte: dictionary.xml
Aquest és el mètode general per exportar la informació que hi ha en una base de dades a un fitxer xml, i la informació d'aquest passar-la al Android.
En l'exemple treballarem amb la base de dades del Langtrainer (MySQL), on agafarem la informació que ens interessa: una relació de les paraules angleses i les seves traduccions. S'ha de destacar que la relació és 1:M, com es pot veure en el fitxer XML: una paraula pot tenir diversos significats o apreciacions.
El mètode és general perquè em pot servir per importar al Android una llista de contactes , de telèfons, d'avisos, alarmes, ToDo, que es poden obtenir de les més diverses aplicacions (que utilitzin bases de dades).
Script php. Generar el fitxer XML
<?php
$dbName = "langtrainer";
$connection = mysql_connect("localhost", "root", "****") or die("Could not connect.");
$db = mysql_select_db($dbName);
$query = "SELECT W.ID_WORD,WORD,TRANSLATION FROM WORD W,TRANSLATION T WHERE W.id_word=T.id_word ORDER BY WORD";
//$query="SELECT * FROM WORD";
$result = mysql_query($query, $connection) or die("Could not complete database query");
$num = mysql_num_rows($result);
if ($num != 0) {
$file= fopen("dictionary.xml", "w");
$_xml ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n";
$_xml .="<dictionary>\r\n";
while ($row = mysql_fetch_array($result)) {
if ($row["ID_WORD"]) {
if ($id_word!=$row["ID_WORD"]){
if ($id_word>0) $_xml .="\t</entry>\r\n";
$_xml .="\t<entry word=\"" . $row["WORD"] . "\">\r\n";
$_xml .="\t\t<translation>" . $row["TRANSLATION"] . "</translation>\r\n";
$id_word=$row["ID_WORD"];
}
else
{
$_xml .="\t\t<translation>" . $row["TRANSLATION"] . "</translation>\r\n";
}
} else {
$_xml .="\t<entry word=\"Nothing Returned\">\r\n";
$_xml .="\t\t<translation>-</translation>\r\n";
$_xml .="\t</entry>\r\n";
}
}
$_xml .="\t</entry>\r\n";
$_xml .="</dictionary>";
fwrite($file, $_xml);
fclose($file);
echo "dictionary.xml was generated";
} else {
echo "no records";
}
?>
Es genera el fitxer dictionary.xml:
<?xml version="1.0" encoding="UTF-8" ?> <dictionary> <entry word="deserve (to)"> <translation>merèixer, ser digne de</translation> </entry> <entry word="dismiss (to)"> <translation>acomiadar, destituir. Refusar</translation> </entry> <entry word="draw (to)"> <translation>dibuixar</translation> <translation>Estirar (pull), treure, atraure</translation> </entry> <entry word="draw breath (to)"> <translation>agafar aire</translation> </entry> <entry word="gills"> <translation>branquies, agalles</translation> </entry> <entry word="hump"> <translation>pujol, puig</translation> </entry> <entry word="lump"> <translation>terròs, tros</translation> </entry> <entry word="shame"> <translation>vergonya, llàstima</translation> </entry> <entry word="snout"> <translation>morro, hocico</translation> </entry> <entry word="spit"> <translation>escupinada, saliva</translation> </entry> <entry word="weird"> <translation>rar, extrany</translation> </entry> <entry word="wound"> <translation>ferir (pp, ferit)</translation> <translation>ferida</translation> </entry> </dictionary>
Com es pot veure, el verb to draw té dos significats
Aplicació Diccionari
Partim del projecte ParsingXML vist anteriorment, i l'adaptem al nostre fitxer XML. Tot i que conceptualment és el mateix, he hagut de canviar coses. En el projecte ParsingXML només es llegia la última entrada XML, i ara s'han de llegir totes. A més, tota la informació de parsejar el fitxer XML s'ha d'acumular en una variable, i finalment volcar-la en el TextView.
Fitxer Diccionari.java:
package com.android.diccionari;
import java.net.URL;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class Diccionari extends Activity {
private final String MY_DEBUG_TAG = "Diccionari";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* Create a new TextView to display the parsingresult later. */
TextView tv = new TextView(this);
try {
/* Create a URL we want to load some xml-data from. */
//URL url = new URL("http://www.anddev.org/images/tut/basic/parsingxml/example.xml");
URL url = new URL("http://wikijoan.dyndns.org/admin/dictionary.xml");
/* Get a SAXParser from the SAXPArserFactory. */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
/* Get the XMLReader of the SAXParser we created. */
XMLReader xr = sp.getXMLReader();
/* Create a new ContentHandler and apply it to the XML-Reader*/
DiccionariHandler myDiccionariHandler = new DiccionariHandler();
xr.setContentHandler(myDiccionariHandler);
/* Parse the xml-data from our URL. */
xr.parse(new InputSource(url.openStream()));
/* Parsing has finished. */
/* Our ExampleHandler now provides the parsed data to us. */
ParsedDiccionariDataSet parsedDiccionariDataSet =
myDiccionariHandler.getParsedData();
/* Set the result to be displayed in our GUI. */
tv.setText(parsedDiccionariDataSet.toString());
} catch (Exception e) {
/* Display any Error to the GUI. */
tv.setText("Error: " + e.getMessage());
Log.e(MY_DEBUG_TAG, "DiccionariError", e);
}
/* Display the TextView. */
this.setContentView(tv);
}
}
Fitxer DiccionariHandler.java:
package com.android.diccionari;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class DiccionariHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private boolean in_dictionary = false;
private boolean in_entry = false;
private boolean in_translation = false;
private ParsedDiccionariDataSet myParsedDiccionariDataSet = new ParsedDiccionariDataSet();
// ===========================================================
// Getter & Setter
// ===========================================================
public ParsedDiccionariDataSet getParsedData() {
return this.myParsedDiccionariDataSet;
}
// ===========================================================
// Methods
// ===========================================================
@Override
public void startDocument() throws SAXException {
this.myParsedDiccionariDataSet = new ParsedDiccionariDataSet();
}
@Override
public void endDocument() throws SAXException {
// Nothing to do
}
/** Gets be called on opening tags like:
* <tag>
* Can provide attribute(s), when xml was like:
* <tag attribute="attributeValue">*/
@Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
if (localName.equals("dictionary")) {
this.in_dictionary = true;
}else if (localName.equals("entry")) {
this.in_entry = true;
// Extract an Attribute
String attrValue = atts.getValue("word");
myParsedDiccionariDataSet.setExtractedWord(attrValue);
}else if (localName.equals("translation")) {
this.in_translation = true;
}
}
/** Gets be called on closing tags like:
* </tag> */
@Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("dictionary")) {
this.in_dictionary = false;
}else if (localName.equals("entry")) {
this.in_entry = false;
}else if (localName.equals("translation")) {
this.in_translation = false;
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
@Override
public void characters(char ch[], int start, int length) {
if(this.in_translation){
myParsedDiccionariDataSet.setExtractedTranslation(new String(ch, start, length));
}
}
}
Fitxer ParsedDictionaryDataSet.java:
package com.android.diccionari;
public class ParsedDiccionariDataSet {
private String extractedWord=null;
private String extractedTranslation=null;
private String extractedAll = "Vocabulari\n==========";
public String getExtractedWord() {
return extractedWord;
}
public void setExtractedWord(String extractedWord) {
this.extractedWord = extractedWord;
extractedAll = extractedAll + "\n"+extractedWord+": ";
}
public String getExtractedTranslation() {
return extractedTranslation;
}
public void setExtractedTranslation(String extractedTranslation) {
this.extractedTranslation = extractedTranslation;
extractedAll = extractedAll + extractedTranslation + ". ";
}
public String toString(){
return extractedAll;
}
}
Fitxer AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.diccionari"
android:versionCode="1"
android:versionName="1.0.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Diccionari"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
creat per Joan Quintana Compte, febrer 2009