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