Using SAXparser to get info to more than one element (Android) - android

I'm new in Android (and in Java too) but now I'm starting to work with web services.
So to understand better how to parse an XML, I started to try this tutorial:
http://www.anddev.org/novice-tutorials-f8/parsing-xml-from-the-net-using-the-saxparser-t353.html
With the XML used in this example:
<outertag>
<innertag sampleattribute="innertagAttribute">
<mytag>anddev.org rulez =)</mytag>
<tagwithnumber thenumber="1337"/>
</innertag>
</outertag>
I understand how it works (I guess), but if the XML is like this:
<outertag>
<innertag sampleattribute="innertagAttribute">
<mytag>anddev.org rulez =)</mytag>
<tagwithnumber thenumber="1337"/>
</innertag>
<innertag sampleattribute="innertagAttribute2">
<mytag>something</mytag>
<tagwithnumber thenumber="14214"/>
</innertag>
</outertag>
What needs to change in the classes of the application to obtain the data of the various elements?
I appreciate any sugestion...
Full source code:
ParseXML.java
package org.anddev.android.parsingxml;
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.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class ParsingXML extends Activity {
private final String MY_DEBUG_TAG = "WeatherForcaster";
/** 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");
/* 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*/
ExampleHandler myExampleHandler = new ExampleHandler();
xr.setContentHandler(myExampleHandler);
/* 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. */
ParsedExampleDataSet parsedExampleDataSet =
myExampleHandler.getParsedData();
/* Set the result to be displayed in our GUI. */
tv.setText(parsedExampleDataSet.toString());
} catch (Exception e) {
/* Display any Error to the GUI. */
tv.setText("Error: " + e.getMessage());
Log.e(MY_DEBUG_TAG, "WeatherQueryError", e);
}
/* Display the TextView. */
this.setContentView(tv);
}
}
ExampleHandler
package org.anddev.android.parsingxml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ExampleHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private boolean in_outertag = false;
private boolean in_innertag = false;
private boolean in_mytag = false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
// ===========================================================
// Getter & Setter
// ===========================================================
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
// ===========================================================
// Methods
// ===========================================================
#Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
#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("outertag")) {
this.in_outertag = true;
}else if (localName.equals("innertag")) {
this.in_innertag = true;
}else if (localName.equals("mytag")) {
this.in_mytag = true;
}else if (localName.equals("tagwithnumber")) {
// Extract an Attribute
String attrValue = atts.getValue("thenumber");
int i = Integer.parseInt(attrValue);
myParsedExampleDataSet.setExtractedInt(i);
}
}
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("outertag")) {
this.in_outertag = false;
}else if (localName.equals("innertag")) {
this.in_innertag = false;
}else if (localName.equals("mytag")) {
this.in_mytag = false;
}else if (localName.equals("tagwithnumber")) {
// Nothing to do here
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(this.in_mytag){
myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
}
}
}
ParsedExampleDataSet
package org.anddev.android.parsingxml;
public class ParsedExampleDataSet {
private String extractedString = null;
private int extractedInt = 0;
public String getExtractedString() {
return extractedString;
}
public void setExtractedString(String extractedString) {
this.extractedString = extractedString;
}
public int getExtractedInt() {
return extractedInt;
}
public void setExtractedInt(int extractedInt) {
this.extractedInt = extractedInt;
}
public String toString(){
return "ExtractedString = " + this.extractedString
+ "nExtractedInt = " + this.extractedInt;
}
}

Problem solved!
Bellow are the sites with useful information:
https://stackoverflow.com/a/4828765
https://stackoverflow.com/a/5709544
http://as400samplecode.blogspot.com/2011/11/android-parse-xml-file-example-using.html
http://www.anddev.org/novice-tutorials-f8/parsing-xml-from-the-net-using-the-saxparser-t353.html
My initial problem was how I should define the class for the data which I wanted to extract from XML. After I figured out how I should do this (reviewing the basic concepts of JAVA programming), I changed the type of data returned by the ExampleHandler to an ArrayList<"class of the data you want return">.
I give below an example:
Example of a XML you want to parse:
<outertag>
<cartag type="Audi">
<itemtag name="model">A4</itemtag>
<itemtag name="color">Black</itemtag>
<itemtag name="year">2005</itemtag>
</cartag>
<cartag type="Honda">
<itemtag name="model">Civic</itemtag>
<itemtag name="color">Red</itemtag>
<itemtag name="year">2001</itemtag>
</cartag>
<cartag type="Seat">
<itemtag name="model">Leon</itemtag>
<itemtag name="color">White</itemtag>
<itemtag name="year">2009</itemtag>
</cartag>
</outertag>
So here you should define a class "car" with proper attributes (String type, model, color, year;), setters and getters...
My suggestion of ExampleHandler for this XML is:
public class ExampleHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private int numberOfItems=3;
private boolean in_outertag = false;
private boolean in_cartag = false;
private boolean[] in_itemtag = new boolean[numberOfItems];
Car newCar = new Car();
private ArrayList<Car> list = new ArrayList<Car>();
// ===========================================================
// Getter & Setter
// ===========================================================
public ArrayList<Car> getParsedData() {
return this.list;
}
// ===========================================================
// Methods
// ===========================================================
#Override
public void startDocument() throws SAXException {
this.list = new ArrayList<Car>();
}
#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("outertag")) {
this.in_outertag = true;
}else if (localName.equals("cartag")) {
this.in_cartag = true;
newCar.setType(atts.getValue("type")); //setType(...) is the setter defined in car class
}else if (localName.equals("itemtag")) {
if((atts.getValue("name")).equals("model")){
this.in_itemtag[0] = true;
}else if((atts.getValue("name")).equals("color")){
this.in_itemtag[1] = true;
}else if((atts.getValue("name")).equals("year")){
this.in_itemtag[2] = true;
}
}
}
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("outertag")) {
this.in_outertag = false;
}else if (localName.equals("cartag")) {
this.in_cartag = false;
Car carTemp = new Car();
carTemp.copy(newCar, carTemp); //this method is defined on car class, and is used to copy the
//properties of the car to another Object car to be added to the list
list.add(carTemp);
}else if (localName.equals("itemtag")){
if(in_itemtag[0]){
this.in_itemtag[0] = false;
}else if(in_itemtag[1]){
this.in_itemtag[1] = false;
}else if(in_itemtag[2]){
this.in_itemtag[2] = false;
}
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(in_itemtag[0]){
newCar.setModel(new String(ch, start, length));
}else if(in_itemtag[1]){
newCar.setColor(new String(ch, start, length));
}else if(in_itemtag[2]){
newCar.setYear(new String(ch, start, length));
}
}
}
After this, you can get the parsed data in the Activity using:
...
ArrayList<Car> ParsedData = myExampleHandler.getParsedData();
...
I hope this helps someone.
Attention: I don't have tested exactly like this, but is almost the same of my solution so it should work...
And sorry for my bad English...

Related

Parsing issue in SAX parser android

I want to parse data following pattern
Pattern Link
My code is below
public class PriceXMLParsingExample extends Activity {
/** Create Object For SiteList Class */
PriceList sitesList = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/** Create a new layout to display the view */
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
/** Create a new textview array to display the results */
TextView name[];
TextView website[];
TextView category[];
try {
/** Handling XML */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Send URL to parse XML Tags */
URL sourceUrl = new URL("http://www.xmlcharts.com/cache/precious-metals.php");
/** Create handler to handle XML Tags ( extends DefaultHandler ) */
PriceXMLHandler myXMLHandler = new PriceXMLHandler();
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
/** Get result from MyXMLHandler SitlesList Object */
sitesList = PriceXMLHandler.sitesList;
website = new TextView[sitesList.getWebsite().size()];
/** Set the result text in textview and add it to layout */
for (int i = 0; i < sitesList.getWebsite().size(); i++) {
website[i] = new TextView(this);
website[i].setText("Name = "+sitesList.getWebsite().get(i));
layout.addView(website[i]);
}
/** Set the layout view to display */
setContentView(layout);
}
}
PriceXMLHandler.java
public class PriceXMLHandler extends DefaultHandler {
Boolean currentElement = false;
String currentValue = null;
public static PriceList sitesList = null;
public static PriceList getSitesList() {
return sitesList;
}
public static void setSitesList(PriceList sitesList) {
PriceXMLHandler.sitesList = sitesList;
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentElement = true;
if (localName.equals("prices"))
{
/** Start */
sitesList = new PriceList();
} else if (localName.equals("currency")) {
/** Get attribute value */
String attr = attributes.getValue("access");
sitesList.setCategory(attr);
}
else if (localName.equals("price")) {
String attr = attributes.getValue("access");
sitesList.setCategory(attr);
}
}
/** Called when tag closing ( ex:- <name>AndroidPeople</name>
* -- </name> )*/
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
/** set value */
if (localName.equalsIgnoreCase("price"))
sitesList.setName(currentValue);
else if (localName.equalsIgnoreCase("currency"))
sitesList.setWebsite(currentValue);
}
/** Called to get tag characters ( ex:- <name>AndroidPeople</name>
* -- to get AndroidPeople Character ) */
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (currentElement) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}
}
PriceList.java
public class PriceList {
/** Variables */
private ArrayList<String> currency = new ArrayList<String>();
private ArrayList<String> price = new ArrayList<String>();
private ArrayList<String> access = new ArrayList<String>();
/** In Setter method default it will return arraylist
* change that to add */
public ArrayList<String> getName() {
return currency;
}
public void setName(String name) {
this.currency.add(name);
}
public ArrayList<String> getWebsite() {
return price;
}
public void setWebsite(String website) {
this.price.add(website);
}
public ArrayList<String> getCategory() {
return access;
}
public void setCategory(String category) {
this.access.add(category);
}
}
When I run above code I get only silver price not whole pattern so how can I solve it any idea?
Here we go.....
Price.java
package com.sof;
public class Price {
private String accessp;
private String pricevalue;
public String getAccessp() {
return accessp;
}
public void setAccessp(String access) {
this.accessp = access;
}
public String getPricevalue() {
return pricevalue;
}
public void setPricevalue(String pricevalue) {
this.pricevalue = pricevalue;
}
}
Currency.java
package com.sof;
import java.util.ArrayList;
public class Currency {
private String accessc;
private ArrayList<Price> prices=new ArrayList<Price>();
public String getAccessc() {
return accessc;
}
public void setAccessc(String access) {
this.accessc = access;
}
public ArrayList<Price> getPrices() {
return prices;
}
public void setPrices(ArrayList<Price> price) {
this.prices = price;
}
}
Prices.java
package com.sof;
import java.util.ArrayList;
public class Prices {
private ArrayList<Currency> currencies=new ArrayList<Currency>();
public ArrayList<Currency> getCurrencies() {
return currencies;
}
public void setCurrencies(ArrayList<Currency> currencies) {
this.currencies = currencies;
}
public void addCurrency(Currency currency)
{
this.currencies.add(currency);
}
}
PriceXMLHandler.java
package com.sof;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class PriceXMLHandler extends DefaultHandler {
Boolean currentElement = false;
String currentValue = null;
public Prices pricesList=new Prices();
public Currency currency=null;
public Price price=null;
boolean bprices = false;
boolean bcurrency = false;
boolean bprice = false;
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentElement = true;
if (qName.equals("prices")) {
bprices=true;
// System.out.println(qName);
} else if (qName.equals("currency")) {
bcurrency=true;
currency=new Currency();
String attr = attributes.getValue("access");
currency.setAccessc(attr);
} else if (qName.equals("price")) {
bprice=true;
price=new Price();
//System.out.println(qName);
String attr = attributes.getValue("access");
price.setAccessp(attr);
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
/** set value */
if (qName.equalsIgnoreCase("price"))
{
}
else if (qName.equalsIgnoreCase("currency"))
{
pricesList.getCurrencies().add(currency);
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (bprice) {
price.setPricevalue(new String(ch, start, length));
currency.getPrices().add(price);
bprice = false;
}
}
}
Finally
Tester.java
package com.sof;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class Tester {
public static void main(String[] args) {
Prices sitesList;
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
InputStream xmlInput = new FileInputStream("src/test.xml");
SAXParser saxParser = factory.newSAXParser();
PriceXMLHandler handler = new PriceXMLHandler();
saxParser.parse(xmlInput, handler);
sitesList = handler.pricesList;
for(Currency currency:sitesList.getCurrencies())
{
System.out.println(currency.getAccessc());
for(Price price:currency.getPrices())
{
System.out.println(price.getAccessp()+"\t"+price.getPricevalue());
}
}
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
e.printStackTrace();
}
}
}
OutPUT Will Be
aud
gold 46.029190755073
palladium 26.341121448078
platinum 51.54654854858
silver 0.71732682032307
brl
gold 98.537459156603
palladium 56.390024161854
platinum 110.34879907615
silver 1.5356247003263
cad
gold 45.011219881119
palladium 25.758567334448
platinum 50.406557073289
silver 0.70146258725235
chf
gold 36.245806009071
palladium 20.742384613034
platinum 40.59046375746
silver 0.56486087085223
cny
gold 244.21529483123
palladium 139.75706796276
platinum 273.48852640726
silver 3.8058931308984
eur
gold 29.556496982569
palladium 16.914294251671
platinum 33.099330699618
silver 0.46061352921044
gbp
gold 24.402090312082
palladium 13.964582343362
platinum 27.327083364375
silver 0.3802863697071
inr
gold 2520.7993626485
palladium 1442.5776571022
platinum 2822.9587484909
silver 39.284570547915
jpy
gold 4148.483313
palladium 2374.052226
platinum 4645.74747
silver 64.650677
mxn
gold 537.06911300288
palladium 307.34849993124
platinum 601.44570550145
silver 8.3697773696277
rub
gold 1412.2617736624
palladium 808.1949364365
platinum 1581.5446434145
silver 22.008930223337
usd
gold 40.39419
palladium 23.11638
platinum 45.2361
silver 0.62951
zar
gold 448.9410405203
palladium 256.91545467956
platinum 502.75402980182
silver 6.9963743404171
Let me know if you face any issues...

Xml parse android code

I am making an application for Android and I need to display an XML file of this page: In the application show Compra="481.3" Venta="485" but i cant "DOLAR SPOT INTERBANCARIO" and Var_por="-0,53" Var_pes="-2,60" hora="10:35". Help me with the code please.
XML image
This is ExampleHandler code
public class ExampleHandler extends DefaultHandler {
private boolean in_Root = false;
private boolean in_Registro = false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
#Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
#Override
public void endDocument() throws SAXException {
}
#Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
if (localName.equals("Root")) {
this.in_Root = true;
}else if (localName.equals("Registro")) {
this.in_Registro = true;
// Extract an Attribute
String attrValue = atts.getValue("Compra");
Float compra = Float.parseFloat(attrValue);
myParsedExampleDataSet.setExtractedCompra(compra);
String attrValue2 = atts.getValue("Venta");
Float venta = Float.parseFloat(attrValue2);
myParsedExampleDataSet.setExtractedVenta(venta);
**String attrValue3 = atts.getValue("Var_por");
Float por = Float.parseFloat(attrValue3);
myParsedExampleDataSet.setExtractedPor(por);**
//its my wrong code for Var_por
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("Root")) {
this.in_Root = false;
}else if (localName.equals("Registro")) {
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(this.in_Registro){
//myParsedExampleDataSet.setExtractedStruct(new String(ch, start, length));
}
}
}
You might check out SimpleXML for something small like that. It works well on Android.
SimpleXML parser
I implemented a solution to this problem recently using Jsoup.
The solution outlined below will both fetch the data from the supplied URL and parse it into an array of Strings.
Setup
The .jar file can be found here.
Instructions on how to include it in an Android app are here.
Implementation
Imports used:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
Function code:
public static ArrayList<String> parseDocument()
{
ArrayList<String> values = new ArrayList<String>();
Document doc;
try {
doc = Jsoup.connect("http://www.bovalpo.com/cgi-local/xml_bcv.pl?URL=7009").get(); // Timeout is in milliseconds
Elements nodes = doc.select("Registro");
values.add( nodes.attr("tipo") );
values.add( nodes.attr("Compra") );
values.add( nodes.attr("Venta") );
values.add( nodes.attr("Var_por") );
// etc
} catch (IOException e) {
e.printStackTrace();
}
return values;
}
All you need to do once the function is returned is read the values from the ArrayList.

Show null value in the emmulator after Parsing the tag through sax parser in android?

I am making an small application in android of webservices through Sax parser my link is
(http://www.anddev.org/images/tut/basic/parsingxml/example.xml)I am able to display the value of ****<**innertag>,******But can't able to display the value of in theTextView
Here is my sorcs code
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ExampleHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private boolean in_outertag = false;
private boolean in_innertag = false;
private boolean in_mytag = false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
// ===========================================================
// Getter & Setter
// ===========================================================
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
// ===========================================================
// Methods
// ===========================================================
#Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
#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("outertag")) {
this.in_outertag = true;
}else if (localName.equals("innertag")) {
//this.in_innertag = true;
String attrValue = atts.getValue("sampleattribute");
myParsedExampleDataSet.setExtractedString(attrValue);
}else if (localName.equals("mytag")) {
//this.in_mytag = true;
String attrValue = atts.getValue("mytag");
myParsedExampleDataSet.setExtractedString1(attrValue);
}else if (localName.equals("tagwithnumber")) {
// Extract an Attribute
String attrValue = atts.getValue("thenumber");
int i = Integer.parseInt(attrValue);
myParsedExampleDataSet.setExtractedInt(i);
}
}
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("outertag")) {
this.in_outertag = false;
}else if (localName.equals("innertag")) {
// this.in_innertag = false;
}else if (localName.equals("mytag")) {
//this.in_mytag = false;
}else if (localName.equals("tagwithnumber")) {
// Nothing to do here
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(this.in_mytag){
myParsedExampleDataSet.setExtractedString1(new String(ch, start, length));
}
}
}![enter image description here][1]
You have this.in_mytag = true commented out in startElement(). Therefore the code block in the characters() function that sets ExtractedString1 isn't executing because in_mytag is false.
One other thing when handling the start of mytag: String attrValue = atts.getValue("mytag"); is unnecessary. It should be handled in the characters() function (I suspect you simply had it for debugging purposes).

Xml Parsing in android

EveryOne I am doing xml parsing like This
public class XMLHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
static ArrayList<Category1> cat_list=new ArrayList<Category1>();
static ArrayList<Products> product_list=new ArrayList<Products>();
Category1 cat;
Products pro;
private boolean in_outertag = false;
private boolean in_innertag = false;
private boolean in_mytag = false;
private boolean in_mytag1 = false;
private boolean in_mytag2 = false;
private boolean in_mytag3 = false;
private XMLDataSet myParsedExampleDataSet = new XMLDataSet();
// ===========================================================
// Getter & Setter
// ===========================================================
public XMLDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
// ===========================================================
// Methods
// ===========================================================
#Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new XMLDataSet();
}
#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("root")) {
this.in_outertag = true;
}else if (localName.equals("Categories")) {
this.in_innertag = true;
}else if (localName.equals("Category")) {
cat =new Category1();
String attrValue = atts.getValue("id");
int i = Integer.parseInt(attrValue);
myParsedExampleDataSet.setExtractedInt(i);
cat.setCatId(i+"");
//cat_id[i]=myParsedExampleDataSet.setExtractedInt(i);
//Log.i("id", cat.setCatId(i+""));
String attrValue1 = atts.getValue("pid");
int i1 = Integer.parseInt(attrValue1);
myParsedExampleDataSet.setExtractedInt(i1);
cat.setPid(i1+"");
//p_id[i1]=myParsedExampleDataSet.setExtractedInt(i1);
//Log.i("pid", myParsedExampleDataSet.setExtractedInt(i1)+"");
this.in_mytag = true;
}else if (localName.equals("title")) {
// Extract an Attribute
this.in_mytag1 = true;
}else if (localName.equals("products")) {
this.in_innertag = true;
}else if (localName.equals("product")) {
pro=new Products();
String attrValue = atts.getValue("catid");
int i = Integer.parseInt(attrValue);
myParsedExampleDataSet.setExtractedInt(i);
pro.setCatId(i+"");
//Log.i("catid", myParsedExampleDataSet.setExtractedInt(i)+"");
this.in_mytag = true;
}else if (localName.equals("name")) {
// Extract an Attribute
this.in_mytag2 = true;
}else if (localName.equalsIgnoreCase("url")) {
// Extract an Attribute
this.in_mytag3 = true;
}
}
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("root")) {
this.in_outertag = false;
}else if (localName.equals("Categories")) {
this.in_innertag = false;
}else if (localName.equals("Category")) {
cat_list.add(cat);
this.in_mytag = false;
}else if (localName.equals("title")) {
this.in_mytag1=false;
}else if (localName.equals("products")) {
this.in_innertag=false;
}else if (localName.equals("product")) {
product_list.add(pro);
this.in_mytag=false;
}else if (localName.equals("name")) {
this.in_mytag2=false;
}else if (localName.equalsIgnoreCase("url")) {
this.in_mytag3=false;
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(this.in_mytag1){
myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
cat.setCatName(new String(ch, start, length));
}
if(this.in_mytag2){
myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
pro.setProductId(new String(ch, start, length));
}
if(this.in_mytag3){
String chars = new String(ch, start, length);
chars = chars.trim();
//myParsedExampleDataSet.setExtractedString(chars);
pro.setUrl(chars);
}
}
}
I parse all thing very good but not url....
The Xml file is like this
<?xml version="1.0" encoding="UTF-16"?>
<products>
<product catid="11">
<name>song1</name>
<url>http://news.google.co.in/news?edchanged=1&ned=en_il</url>
</product>
I got the result ned=en_il only
Please Help me, Where i am wrong??
Thankx
You may try by warping your <url> node into CDATA tag like this
<url><![CDATA[http://news.google.co.in/news?edchanged=1&ned=en_il]]></url>
to rectify the issue.
I would recommend using android.sax for parsing it is much easier. You can read about it here http://www.ibm.com/developerworks/opensource/library/x-android/
The problem is likely to be in your characters method.
This method may be called several times for a given element, your code is assuming it will only be called once. e.g. It is likely called for "http://news.google.co.in", "/news?edchanged=1&" and "ned=en_il"
If you append the characters to appropriate properties instead of setting them it will probably work.

Android: Sax parsing returns null values and retrieve values in tags of same name

I have these XML on a URL
<?xml version="1.0" encoding="ISO-8859-1" ?>
<Phonebook>
<PhonebookEntry>
<firstname>John</firstname>
<lastname>Connor</lastname>
<Address>5,Downing Street</Address>
<Phone loc="home">9875674567</Phone>
<Phone loc="work">9875674567</Phone>
<Phone loc="mobile">78654562341</Phone>
</PhonebookEntry>
<PhonebookEntry>
<firstname>John</firstname>
<lastname>Smith</lastname>
<Address>6,Downing Street</Address>
<Phone loc="home">678-56-home</Phone>
<Phone loc="work">678-59-work</Phone>
<Phone loc="mobile">678-85-mobile</Phone>
</PhonebookEntry>
</Phonebook>
I was able to extract the values on firstname, lastname and Address, but when it comes to Phone tags, my code returns null values. Here are my code:
ParsingXML.java
package com.example.parsingxml;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;
import java.net.URLConnection;
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.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class ParsingXML extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
//System.setProperty("http.proxyHost"," 129.188.69.100 ");
//System.setProperty("http.proxyPort","1080");
//System.setProperty("http.nonProxyHosts","10.228.97.76");
/* 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://somedomain.com/jm/sampleXML.xml");
URLConnection ucon = url.openConnection();
/* 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*/
ExampleHandler myExampleHandler = new ExampleHandler();
xr.setContentHandler(myExampleHandler);
/* 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. */
ParsedExampleDataSet parsedExampleDataSet =
myExampleHandler.getParsedData();
/* Set the result to be displayed in our GUI. */
tv.setText(parsedExampleDataSet.toString());
} catch (Exception e) {
/* Display any Error to the GUI. */
tv.setText("Error: " + e.getMessage());
}
/* Display the TextView. */
this.setContentView(tv);
}
}
ExampleHandler.java
package com.example.parsingxml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ExampleHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private boolean in_outertag = false;
private boolean in_innertag = false;
private boolean in_firstname = false;
private boolean in_lastname= false;
private boolean in_Address=false;
private boolean in_Phone=false;
private boolean in_homePhone=false;
private boolean in_workPhone=false;
private boolean in_mobilePhone=false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
// ===========================================================
// Getter & Setter
// ===========================================================
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
// ===========================================================
// Methods
// ===========================================================
#Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
#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("PhoneBook")) {
this.in_outertag = true;
}else if (localName.equals("PhonebookEntry")) {
this.in_innertag = true;
}else if (localName.equals("firstname")) {
this.in_firstname = true;
}else if (localName.equals("lastname")) {
this.in_lastname= true;
}else if(localName.equals("Address")) {
this.in_Address= true;
}else if (localName.equals("Phone")){
this.in_Phone=true;
String phoneattr=atts.getValue("loc");
if(phoneattr.equals("home")){
this.in_homePhone=true;
}else if(phoneattr.equals("work")){
this.in_workPhone=true;
}else if(phoneattr.equals("mobile")){
this.in_mobilePhone=true;
}
}
}
//else if (localName.equals("tagwithnumber")) {
// }
// Extract an Attribute
// String attrValue = atts.getValue("thenumber");
// int i = Integer.parseInt(attrValue);
// myParsedExampleDataSet.setExtractedInt(i);
// }
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("Phonebook")) {
this.in_outertag = false;
}else if (localName.equals("PhonebookEntry")) {
this.in_innertag = false;
}else if (localName.equals("firstname")) {
this.in_firstname = false;
}else if (localName.equals("lastname")) {
this.in_lastname= false;
}else if(localName.equals("Address")) {
this.in_Address= false;
}else if(localName.equals("Phone")) {
this.in_Phone=false;
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(this.in_firstname){
myParsedExampleDataSet.setfirstname(new String(ch, start, length));
}
if(this.in_lastname){
myParsedExampleDataSet.setlastname(new String(ch, start, length));
}
if(this.in_Address){
myParsedExampleDataSet.setAddress(new String(ch, start, length));
}
if(this.in_homePhone){
myParsedExampleDataSet.sethomePhone(new String(ch, start, length));
}
if(this.in_workPhone){
myParsedExampleDataSet.setworkPhone(new String(ch, start, length));
}
if(this.in_mobilePhone){
myParsedExampleDataSet.setmobilePhone(new String(ch, start, length));
}
}
}
ParsedExampleDataSet.java
package com.example.parsingxml;
public class ParsedExampleDataSet {
private String firstname = null;
private String lastname=null;
private String Address=null;
private String Phone=null;
private String homephone=null;
private String workphone=null;
private String mobilephone=null;
//Firstname
public String getfirstname() {
return firstname;
}
public void setfirstname(String firstname) {
this.firstname = firstname;
}
//Lastname
public String getlastname(){
return lastname;
}
public void setlastname(String lastname){
this.lastname=lastname;
}
//Address
public String getAddress(){
return Address;
}
public void setAddress(String Address){
this.Address=Address;
}
//Phone
public String getPhone(){
return Phone;
}
public void sethomePhone(String homePhone){
this.homephone=homePhone;
}
public void setworkPhone(String homePhone){
this.homephone=homePhone;
}
public void setmobilePhone(String homePhone){
this.homephone=homePhone;
}
public String toString(){
return "firstname: " + this.firstname + "\n" + "lastname=: " + this.lastname + "\n" + "Address: " + this.Address+ "\n" + "homephone: " + this.homephone + "\n" + "workphone: " + this.workphone + "\n" + "mobilephone: " + this.mobilephone;
}
}
Another thing how can I retrieve both values in PhonebookEntry tags?
I'm kinda new to java and android dev, many thanks in advance! :)
This code makes the incorrect assumption that the characters method will be called only once between the startElement and endElement calls for a tag.
Instead of having the logic for setting the values in the characters method, you need initialize a buffer in the startElement method, collect characters into the buffer in the characters method, and then make the assignments and clear the buffer in the endElement method.
EDIT:
Actually, there were a few other issues in your code...
You had setMobilePhone and setWorkPhone in your model class setting the homePhone field... An inevitable risk when you copy-modify code.
And your handler was only creating one result, and would have overwritten and only returned the last one in the file.
I've played with it, changed some of the methods more to Java standard naming, and changed some of the xml to CamelCase as well.
Revised XML:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<PhoneBook>
<PhoneBookEntry>
<FirstName>John</FirstName>
<LastName>Connor</LastName>
<Address>5,Downing Street</Address>
<Phone loc="home">9875674567</Phone>
<Phone loc="work">9875674567</Phone>
<Phone loc="mobile">78654562341</Phone>
</PhoneBookEntry>
<PhoneBookEntry>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
<Address>6,Downing Street</Address>
<Phone loc="home">678-56-home</Phone>
<Phone loc="work">678-59-work</Phone>
<Phone loc="mobile">678-85-mobile</Phone>
</PhoneBookEntry>
</PhoneBook>
Revised ParsedExampleDataSet:
public class ParsedExampleDataSet {
private String firstName = null;
private String lastName =null;
private String address =null;
private String homePhone =null;
private String workPhone =null;
private String mobilePhone =null;
//Firstname
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
//Lastname
public String getLastName(){
return lastName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
//address
public String getAddress(){
return address;
}
public void setAddress(String Address){
this.address =Address;
}
public void setHomePhone(String homePhone){
this.homePhone =homePhone;
}
public void setWorkPhone(String homePhone){
this.workPhone =homePhone;
}
public void setMobilePhone(String homePhone){
this.mobilePhone =homePhone;
}
public String toString(){
return "firstName: " + this.firstName + "\n" + "lastName=: " + this.lastName + "\n" + "address: " + this.address + "\n" + "homePhone: " + this.homePhone + "\n" + "workPhone: " + this.workPhone + "\n" + "mobilePhone: " + this.mobilePhone;
}
}
And the handler that does the parsing:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.List;
public class ExampleHandler extends DefaultHandler {
// ===========================================================
// Fields
// ===========================================================
private boolean in_homePhone = false;
private boolean in_workPhone = false;
private boolean in_mobilePhone = false;
private StringBuffer stringBuffer;
private List<ParsedExampleDataSet> myParsedExampleDataSets;
private ParsedExampleDataSet myParsedExampleDataSet;
// ===========================================================
// Methods
// ===========================================================
public List<ParsedExampleDataSet> getParsedData() {
return myParsedExampleDataSets;
}
#Override
public void startDocument() throws SAXException {
myParsedExampleDataSets = new ArrayList<ParsedExampleDataSet>();
stringBuffer = new StringBuffer();
}
#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 (qName.equals("PhoneBookEntry")) {
myParsedExampleDataSet = new ParsedExampleDataSet();
}
if (qName.equals("Phone")) {
String phoneLocation = atts.getValue("loc");
if (phoneLocation.equals("home")) {
this.in_homePhone = true;
} else if (phoneLocation.equals("work")) {
this.in_workPhone = true;
} else if (phoneLocation.equals("mobile")) {
this.in_mobilePhone = true;
}
}
}
/**
* Gets be called on closing tags like:
* </tag>
*/
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
String result = stringBuffer.toString();
stringBuffer.setLength(0);
if (in_homePhone) {
myParsedExampleDataSet.setHomePhone(result);
in_homePhone = false;
}
else if (in_mobilePhone) {
myParsedExampleDataSet.setMobilePhone(result);
in_mobilePhone = false;
}
else if (in_workPhone) {
myParsedExampleDataSet.setWorkPhone(result);
in_workPhone = false;
}
else if (qName.equals("FirstName")) {
myParsedExampleDataSet.setFirstName(result);
}
else if (qName.equals("LastName")) {
myParsedExampleDataSet.setLastName(result);
}
else if (qName.equals("Address")) {
myParsedExampleDataSet.setAddress(result);
}
else if (qName.equals("PhoneBookEntry")) {
myParsedExampleDataSets.add(myParsedExampleDataSet);
}
}
/**
* Gets be called on the following structure:
* <tag>characters</tag>
*/
#Override
public void characters(char ch[], int start, int length) {
stringBuffer.append(new String(ch, start, length));
}
}
It puts some likely unwanted whitespace in the fields, but I suspect you can figure out how to trim that.
Calling it, you get a list rather than a single object, but other than dealing with that, your calling code shouldn't have to change too much. I didn't try to work with that, as I'm not doing any of this on android.
Also to get the attributes from an element you can use something like this:
You get the attributes from the atts Attributes in the startElement method.
}else if (localName.equals("Phone")){
this.in_Phone=true;
int length = atts.getLength();
System.out.println("length = " + length);
for(int i = 0; i < length; i++){
String name = atts.getQName(i);
System.out.println(name);
String value = atts.getValue(i);
System.out.println(value);
if(name.equals("loc")){
if(value.equals("home")){
this.in_homePhone=true;
}else if(value.equals("work")){
this.in_workPhone=true;
}else if(value.equals("mobile")){
this.in_mobilePhone=true;
}
}
}
}

Categories

Resources