I'm a noob to android and I'm trying to learn how to parse xml with the SAX parser. I've written a test application to try to implement it, but i can't seem to make it work. I want my textview to display corresponding values from an xml but it's not working. Can anyone help?
Parser
public class ParseTestActivity extends Activity implements View.OnClickListener {
/** Called when the activity is first created. */
final static String TAG = "spotxml";
TextView tv;
WebView xml;
Button help, help2;
int livespot = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.textView1parsed);
help = (Button) findViewById(R.id.button1);
help2 = (Button) findViewById(R.id.button2);
help.setOnClickListener(this);
help2.setOnClickListener(this);
xml = (WebView) findViewById(R.id.webView1);
try{
xml.loadUrl("http://www.xmlcharts.com/cache/precious-metals.xml");
}catch (Exception e){
e.printStackTrace();
}
try{
URL xmlcharts = new URL("http://www.xmlcharts.com/cache/precious-metals.xml");
//InputSource local = new InputSource(getResources().openRawResource(R.raw.preciousmetals));
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
HandlingXMLStuff doingWork = new HandlingXMLStuff();
xr.setContentHandler(doingWork);
xr.parse(new InputSource(xmlcharts.openStream()));
//xr.parse(local);
XMLDataCollected information = doingWork.getInformation();
//String information = doingWork.getInformation();
tv.setText(information.toString());
livespot = Integer.parseInt(information.toString());
}catch(Exception e){
Toast.makeText(ParseTestActivity.this, "Error", Toast.LENGTH_LONG).show();
Log.e(TAG, "WeatherQueryError", e);
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.button1:
try{
URL xmlcharts = new URL("http://www.xmlcharts.com/cache/precious-metals.xml");
//InputSource local = new InputSource(getResources().openRawResource(R.raw.preciousmetals));
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
HandlingXMLStuff doingWork = new HandlingXMLStuff();
xr.setContentHandler(doingWork);
xr.parse(new InputSource(xmlcharts.openStream()));
//xr.parse(local);
XMLDataCollected information = doingWork.getInformation();
//String information = doingWork.getInformation();
tv.setText(information.toString());
livespot = Integer.parseInt(information.toString());
}catch(Exception e){
Toast.makeText(ParseTestActivity.this, "Error", Toast.LENGTH_LONG).show();
Log.e(TAG, "WeatherQueryError", e);
}
break;
case R.id.button2:
try{
//URL xmlcharts = new URL("http://www.xmlcharts.com/cache/precious-metals.xml");
InputSource local = new InputSource(getResources().openRawResource(R.raw.preciousmetals));
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
HandlingXMLStuff doingWork = new HandlingXMLStuff();
xr.setContentHandler(doingWork);
//xr.parse(new InputSource(xmlcharts.openStream()));
xr.parse(local);
XMLDataCollected information = doingWork.getInformation();
//String information = doingWork.getInformation();
tv.setText(information.toString());
livespot = Integer.parseInt(information.toString());
}catch(Exception e){
Toast.makeText(ParseTestActivity.this, "Error", Toast.LENGTH_LONG).show();
Log.e(TAG, "WeatherQueryError", e);
}
break;
}
}}
Content Handler
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class HandlingXMLStuff extends DefaultHandler {
private boolean in_prices = false;
private boolean in_pricelist = false;
private boolean in_uspricegold = false;
private boolean in_uspricesilver = false;
String gs = null;
String ss = null;
private XMLDataCollected info = new XMLDataCollected();
//public String getInformation(){
// return info.datatoString();
//}
public XMLDataCollected getInformation(){
return this.info;
}
#Override
public void startDocument() throws SAXException {
this.info = new XMLDataCollected();
}
#Override
public void endDocument() throws SAXException {
// Nothing to do
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
if (localName.equalsIgnoreCase("prices")) {
this.in_prices = true ;
}else if (localName.equalsIgnoreCase("pricelist")) {
String attrValue = attributes.getValue("currency");
if (attrValue.equalsIgnoreCase("usd")){
this.in_pricelist = true;
}else if (localName.equalsIgnoreCase("price")){
String attrValue2 = attributes.getValue("commodity");
if (attrValue2.equalsIgnoreCase("gold")){
this.in_uspricegold = true;
}else if (localName.equalsIgnoreCase("price")){
String attrValue3 = attributes.getValue("commodity");
if (attrValue3.equalsIgnoreCase("silver")){
this.in_uspricesilver = true;
}
}}}
}
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equalsIgnoreCase("prices")) {
this.in_prices = false;
}else if (localName.equalsIgnoreCase("pricelist")) {
this.in_pricelist = false;
}else if (localName.equalsIgnoreCase("price")) {
this.in_uspricegold = false;
}else if (localName.equalsIgnoreCase("price")) {
this.in_uspricesilver = false;
}
}
#Override
public void characters(char[] ch, int start, int length)throws SAXException {
if(this.in_uspricegold) {
//info.setSpotGold(new String (ch, start, length));
//}
int spotgold = Integer.parseInt(new String (ch, start, length));
info.setSpotGold(spotgold);
this.in_uspricegold = false;
}else{}
if(this.in_uspricesilver){
//info.setSpotSilver(new String(ch, start, length));
// }
int spotsilver = Integer.parseInt(new String(ch, start, length));
info.setSpotSilver(spotsilver);
this.in_uspricesilver = false;
}else{}
}
}
Collected Data Set
public class XMLDataCollected{
private int spotsilver = 0;
private int spotgold = 0;
public int getSpotGold() {
return spotgold;
}
public void setSpotGold(int spotgold){
this.spotgold = spotgold;
}
public int getSpotSilver() {
return spotsilver;
}
public void setSpotSilver(int spotsilver){
this.spotsilver = spotsilver;
}
public String toString(){
return "gold " + spotgold + " silver "+ spotsilver;
}
}
First of all your method characters has to be much simpler. The only thing that it does is to read the characters between the tags. It will be like this:
public void characters(char[] ch, int start, int end) {
buffer.append(new String(ch, start, end));
}
As you can see I'm using a StringBuffer as a private field. It's instantiate at the beginning of the startElement method and "resetted" at the beginning of the endElement.
value = buffer.toString();
buffer.setLength(0);
The field value will actually keep the real value of the field.
All my class for reference:
private String value;
private StringBuffer buffer;
#Override
public void startElement(
String nameSpaceURI,
String localName,
String qName,
Attributes atts
) {
buffer = new StringBuffer();
if(localName.equals("myTag"))
bean = new Bean();
}
public void endElement(
String uri,
String localName,
String qName) {
value = buffer.toString();
buffer.setLength(0);
if(localName.equals("myTag") {
bean.setSomething(value);
}
}
public void characters(char[] ch, int start, int end) {
buffer.append(new String(ch, start, end));
}
Hope this helps. :)
EDIT
Here the code adapted to the op xml. I haven't tried it but SHOULD work. ;)
private String value;
private StringBuffer buffer;
private XMLCOllected info;
private boolean inPriceList;
private boolean inGold;
private boolean inSilver;
#Override
public void startElement(
String nameSpaceURI,
String localName,
String qName,
Attributes atts
) {
buffer = new StringBuffer();
if(localName.equals("prices")) {
this.info = new XMLCollected();
} else if(localName.equals("pricelist")) {
String attr = atts.getValue("currency");
if(attr.equals("usd")) {
this.inPriceList = true;
}
} else if(localName.equals("price") && inPrices) {
String attr = atts.getValue("commodity");
if(attr.equals("gold")) {
this.inGold = true;
} else if(attr.equals("silver")) {
this.inSilver = true;
}
}
}
public void endElement(
String uri,
String localName,
String qName) {
value = buffer.toString();
buffer.setLength(0);
if(localName.equals("price") && inGold && inPriceList) {
this.info.setSpotGold(value);
this.inGold = false;
} else if(localName.equals("price") && inSilver && inPriceList) {
this.info.setSpotSilver(value);
this.inSilver = false;
} else if(localName.equals("pricelist")) {
this.inPriceList = false;
}
}
public void characters(char[] ch, int start, int end) {
buffer.append(new String(ch, start, end));
}
Related
I am creating the recovery of text using XML from a URL. I get the text. But I have a problem.
When the text of an item of the XML is large, in the TextView not shows all text of the XML.
What can be the error?
ACTIVITY
class tareaAsyncHorariosTarifas extends AsyncTask<Void, Void, Void> {
XmlReader helper;
#Override
protected Void doInBackground(Void... params) {
helper = new XmlReader(color);
helper.get();
return null;
}
#Override
protected void onPostExecute(Void result) {
StringBuilder builder = new StringBuilder();
for (HorariosTarifasObj post : helper.posts) {
builder.append(post.getHorarios());
}
if(builder.toString().equals("")) {
horario2.setText("-");
} else {
horario2.setText(Html.fromHtml(builder.toString()));
}
builder = new StringBuilder();
for (HorariosTarifasObj post : helper.posts) {
builder.append(post.getTarifas());
}
if(builder.toString().equals("")) {
tarifa2.setText("-");
} else {
tarifa2.setText(Html.fromHtml(builder.toString()));
}
}
}
XML READER
public XmlReader(String color) {
this.color = color;
}
public void get() {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
reader.setContentHandler(this);
InputStream inputStream = new URL(URL + color + ".xml").openStream();
reader.parse(new InputSource(inputStream));
} catch (Exception e) {
}
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currTag = true;
currTagVal = "";
if (localName.equals("color")) {
post = new HorariosTarifasObj();
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
currTag = false;
if(localName.equalsIgnoreCase("horarios")) {
post.setHorarios(currTagVal);
} else if(localName.equalsIgnoreCase("tarifas")) {
post.setTarifas(currTagVal);
} else if (localName.equalsIgnoreCase("color")) {
posts.add(post);
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (currTag) {
currTagVal = currTagVal + new String(ch, start, length);
currTag = false;
}
}
In internet I got a code to download the text of an XML from a URL. The works ok. My problem is that I have to download many XML simultaneously.
I can to improve my code to make downloading faster? thanks
XMLParser
public XmlReader(String monumento) {
this.monumento = monumento;
}
public void get() {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
reader.setContentHandler(this);
InputStream inputStream = new URL(URL + monumento + ".xml").openStream();
reader.parse(new InputSource(inputStream));
} catch (Exception e) {
}
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currTag = true;
currTagVal = "";
if (localName.equals("monumento")) {
post = new HorariosTarifasObj();
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
currTag = false;
if(localName.equalsIgnoreCase("horarios")) {
post.setHorarios(currTagVal);
} else if(localName.equalsIgnoreCase("tarifas")) {
post.setTarifas(currTagVal);
} else if (localName.equalsIgnoreCase("monumento")) {
posts.add(post);
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (currTag) {
currTagVal = currTagVal + new String(ch, start, length);
currTag = false;
}
}
ACTIVITY.java
class tareaAsyncHorariosTarifas extends AsyncTask<Void, Void, Void> {
XmlReader helper;
#Override
protected Void doInBackground(Void... params) {
helper = new XmlReader(monumento);
helper.get();
return null;
}
#Override
protected void onPostExecute(Void result) {
StringBuilder builder = new StringBuilder();
for (HorariosTarifasObj post : helper.posts) {
builder.append(post.getHorarios());
}
if(builder.toString().equals("")) {
horario2.setText("-");
} else {
horario2.setText(Html.fromHtml(builder.toString()));
}
builder = new StringBuilder();
for (HorariosTarifasObj post : helper.posts) {
builder.append(post.getTarifas());
}
if(builder.toString().equals("")) {
tarifa2.setText("-");
} else {
tarifa2.setText(Html.fromHtml(builder.toString()));
}
}
}
How can I show XML tag values on basis of particular condition using local XML parsing.
E.g. I have this XML file stored in assets folder,
<language>
<languagename>English</languagename>
<contact>EContact</contact>
<update>EUpdate</update>
</language>
<language>
<languagename>Hebrew</languagename>
<contact>HContact</contact>
<update>HUpdate</update>
</language>
I have two buttons, when I click English I want to show data Regarding English and when I click Hebrew , I want to show only Hebrew. Please provide help.
Thanks
This is the XML parser Function it takes the XML as String.
public class XMLParser {
public static void parser(String s) {
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
MyXMLhandler h = new MyXMLhandler();
xr.setContentHandler(h);
// Log.e("string", s);
xr.parse(new InputSource(new StringReader(s)));
} catch (ParserConfigurationException e) {
Log.e("ParserError", e.getMessage());
} catch (SAXException e) {
Log.e("SAXError", e.getMessage());
} catch (IOException e) {
Log.e("IOError", e.getMessage());
}
}
}
Use this handler class to extract the information that u need:
public class MyXMLhandler extends DefaultHandler {
private boolean language = false;
private boolean languagename = false;
private boolean contact = false;
private boolean update = false;
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equalsIgnoreCase("language")) {
language = true;
} else if (localName.equalsIgnoreCase("languagename")) {
languagename = true;
} else if (localName.equalsIgnoreCase("contact")) {
contact = true;
} else if (localName.equalsIgnoreCase("update")) {
update = true;
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equalsIgnoreCase("language")) {
language = false;
} else if (localName.equalsIgnoreCase("languagename")) {
languagename = false;
} else if (localName.equalsIgnoreCase("contact")) {
contact = false;
} else if (localName.equalsIgnoreCase("update")) {
update = false;
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (language == true) {
String s = new String(ch, start, length);
Log.w("Language", s);
}
if (languagename == true) {
String s = new String(ch, start, length);
Log.w("Languagename", s);
}
if (contact == true) {
String s = new String(ch, start, length);
Log.w("contact", s);
}
if (update == true) {
String s = new String(ch, start, length);
Log.w("update", s);
}
}
}
Use this function above and modify it to solve ur problem
I am making an application for Android and I need to display an XML file of this page:http://www.bovalpo.com/cgi-local/xml_bcv.pl?URL=7009
I tried the solutions given on the page but I find it wrong since it is not displayed when you run the application. I just want to show "tipo= DOLAR SPOT INTERCAMBIO"
This is the XML CODE
and this is my code:
xmlpruebaprueba.jar
XMLdataCollected sitesList= null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xmlpruebaprueba);
//creando un Layout
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
//creando TextView
TextView Registro[];
TextView Tipo[];
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
URL sourceURL = new URL("http://www.bovalpo.com/cgi-local/xml_bcv.pl?URL=7009");
handlingXml HandlingXml = new handlingXml();
xr.setContentHandler(HandlingXml);
xr.parse(new InputSource(sourceURL.openStream()));
}catch (Exception e){
System.out.println("XML Parsing Exception= " + e);
}
sitesList = handlingXml.sitesList;
Registro = new TextView[sitesList.getRegistro().size()];
Tipo = new TextView[sitesList.getTipo().size()];
for (int i = 0; i < sitesList.getRegistro().size(); i++) {
Registro[i] = new TextView(this);
Registro[i].setText("Registro = "+sitesList.getRegistro().get(i));
Tipo[i] = new TextView(this);
Tipo[i].setText("Tipo = "+sitesList.getTipo().get(i));
layout.addView(Registro[i]);
layout.addView(Tipo[i]);
}
}
}
and this is my handler
Boolean currentElement = false;
String currentValue = null;
public static XMLdataCollected sitesList = null;
public static XMLdataCollected getDataCollected (){
return sitesList;
}
public static void setSitesList(XMLdataCollected sitesList){
handlingXml.sitesList = sitesList;
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
currentElement = true;
if(localName.equals("Root"))
{
sitesList = new XMLdataCollected();
}else if (localName.equals("Registro")){
String attr = attributes.getValue("tipo");
sitesList.setTipo(attr);
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
currentElement = false;
if (localName.equalsIgnoreCase("Registro"))
sitesList.setRegistro(currentValue);
else if (localName.equalsIgnoreCase("Root"))
sitesList.setRoot(currentValue);
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
if (currentElement) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}
}
and this is my dataCollected
public class XMLdataCollected {
private ArrayList<String> root = new ArrayList<String>();
private ArrayList<String> registro = new ArrayList<String>();
private ArrayList<String> tipo = new ArrayList<String>();
public ArrayList<String> getRoot (){
return root;
}
public void setRoot(String root){
this.root.add(root);
}
public ArrayList<String> getRegistro (){
return registro;
}
public void setRegistro(String registro){
this.registro.add(registro);
}
public ArrayList<String> getTipo (){
return tipo;
}
public void setTipo(String tipo){
this.tipo.add(tipo);
}
}
You are calling your Web Request on main UI thread.
PLEASE DO NOT DO THIS
use AsyncTask to call web your request.
i parse the xml file and all data will parsed but i dont understand how to set this data in textview ? give me some idea about that
public class GtuItemXMLHandler extends DefaultHandler {
Gtudownload gtudownload;
Questionpaper questionpaper;
// Show me the XML.
private String currentString = "";
private String charactersString = "";
private Branch branch;
private Year year;
private Semester semester;
private int branchCount = 0;
private int yearCount = 0;
private int semesterCount = 0;
// private ArrayList<Gtudownload> itemsList = new ArrayList<Gtudownload>();
//
// public ArrayList<Gtudownload> getItemsList() {
// return itemsList;
// }
public Gtudownload getGtudownload(){
return this.gtudownload;
}
public Questionpaper getQuestionpaper()
{
return this.questionpaper;
}
// Called when tag starts
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
Log.i("GTU ", localName);
if (localName.equalsIgnoreCase("Gtudownload")) {
gtudownload = new Gtudownload();
currentString = "Gtudownload";
} else if (localName.equalsIgnoreCase("Questionpaper")) {
gtudownload.setQuestionpaper(new Questionpaper());
gtudownload.getQuestionpaper().setBranchList(new ArrayList<Branch>());
currentString = "Questionpaper";
} else if (localName.equalsIgnoreCase("Branch")) {
branch = new Branch();
gtudownload.getQuestionpaper().getBranchList().add(branch);
gtudownload.getQuestionpaper().getBranchList().get(branchCount).setYearList(new ArrayList<Year>());
currentString = "Branch";
Log.i("Branch", attributes.getValue("value"));
branch.setValue(attributes.getValue("value"));
} else if (localName.equalsIgnoreCase("Year")) {
year = new Year();
gtudownload.getQuestionpaper().getBranchList().get(branchCount).getYearList().add(year);
gtudownload.getQuestionpaper().getBranchList().get(branchCount).getYearList().get(yearCount).setSemesterList(new ArrayList<Semester>());
currentString = "Year";
Log.i("Year ", attributes.getValue("value"));
year.setValue(attributes.getValue("value"));
} else if (localName.equalsIgnoreCase("semester")) {
semester = new Semester();
currentString = "semester";
Log.i("Semester ", attributes.getValue("value"));
semester.setValue(attributes.getValue("value"));
gtudownload.getQuestionpaper().getBranchList().get(branchCount).getYearList().get(yearCount).getSemesterList().add(semester);
} else if (localName.equalsIgnoreCase("url")){
currentString = "url";
}
}
// Called when tag closing
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(localName.equalsIgnoreCase("Questionpaper")){
branchCount=0;
}else if(localName.equalsIgnoreCase("Branch")){
yearCount = 0;
branchCount++;
}else if(localName.equalsIgnoreCase("Year")){
semesterCount = 0;
yearCount++;
}else if(localName.equalsIgnoreCase("semester")){
semesterCount++;
}else if(localName.equalsIgnoreCase("url")){
gtudownload.getQuestionpaper().getBranchList().get(branchCount).getYearList().get(yearCount).getSemesterList().get(semesterCount).setUrl(charactersString);
Log.i("URL", charactersString);
}
currentString = "";
charactersString= "";
}
// Called to get tag characters
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
charactersString = new String(ch, start, length);
charactersString = charactersString.trim();
}
}
this is my activity and how can i set this parsing data in into textview
public class GtudldActivity extends Activity {
/** Called when the activity is first created. */
private TextView xmlOutput;
TextView example[];
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
xmlOutput = (TextView) findViewById(R.id.xmlOutput);
Gtudownload gtudownload = parseXML();
}
private Gtudownload parseXML() {
Gtudownload gtudownload = null;
try {
Log.w("AndroidParseXMLActivity", "Start");
/** Handling XML */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
GtuItemXMLHandler myXMLHandler = new GtuItemXMLHandler();
xr.setContentHandler(myXMLHandler);
InputSource is = new InputSource(getResources().openRawResource(R.raw.mgtu));
gtudownload = myXMLHandler.getGtudownload();
Log.i("Data",gtudownload+"");
xr.parse(is);
} catch (Exception e) {
Log.w("AndroidParseXMLActivity", e);
}
//xmlOutput.setText(gtudownload.toString());
return gtudownload;
}
}
You'll get so many examples for this on google. I am showing you one of the. Just try this
I hope it may help you. If you've any doubt, just post it here