Assume that I have file XML like this :
<?xml version="1.0"?>
<P>
<Content>
<id>1016576</id>
<date>20.08.2012</date>
<placeOfBirth>KUALA LUMPUR</placeOfBirth>
</Content>
<Content>
<id>1016620</id>
<date>20.08.2012</date>
<placeOfBirth>SINGAPORE</placeOfBirth>
</Content>
<Content>
<id>1020907</id>
<date>20.08.2012</date>
<placeOfBirth>SINGAPORE</placeOfBirth>
</Content>
</P>
I want to parse all the text and insert into database table which have _id, date and placeOfBirth column. I've tried this :
Activity activity1 = this;
String str="";
Resources res = activity1.getResources();
XmlResourceParser xmlPharser = res.getXml(R.xml.fileXML);
String id,date,pob;
//database
final databaseHelper myDbHelper = new databaseHelper(this);
myDbHelper.open();
//insert into table while parsing xml
try {
xmlPharser.next();
int eventType = xmlPharser.getEventType();
String event = ""+eventType;
Log.d("Event", event);
while (eventType != XmlPullParser.END_DOCUMENT)
{
if(eventType == XmlPullParser.START_TAG )
{
if( xmlPharser.getName() == "id")
{
id=xmlPharser.getText();
}
else if ( xmlPharser.getName() == "date" )
{
date = xmlPharser.getText();
}
else if ( xmlPharser.getName() == "placeOfBirth" )
{
pob = xmlPharser.getText();
}
myDbHelper.insertData(id,date,pob);
myDbHelper.close();
}
eventType = xmlPharser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
It doesn't get any error LogCat display, but it dosen't test the condition at each START_TAG.
How can I resolve this problem...
All answer would be appreciated..thanks
Parsing XML can get really nasty if you're not careful, specially with this parsers; you could try some other with simpler APIs or clearer ways of going through the hierarchy (ie. JDOM). You should also take a look at the examples at the Android developer's site, it's really straight forward (Parsing XML Data).
All that been said, I fixed it for you. This should work (at least it does for me). Be careful though, it doesn't have any error checking on malformed XML or database stuff.
import java.io.IOException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
XmlResourceParser parser = getResources().getXml(R.xml.filexml);
final databaseHelper myDbHelper = null;
try {
myDbHelper = new databaseHelper(this);
myDbHelper.open();
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("Content")) {
String id = null, date = null, pob = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
name = parser.getName();
if (name.equals("id")) {
id = readText(parser);
} else if (name.equals("date")) {
date = readText(parser);
} else if (name.equals("placeOfBirth")) {
pob = readText(parser);
}
}
myDbHelper.insertData(id,date,pob);
}
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (myDbHelper != null) {
myDbHelper.close();
}
}
}
private String readText(XmlPullParser parser) throws IOException,
XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
One more comment, change the xml file name to lowercase ;)
Related
I have a Problem with my android app. It always crashes, when I push the Button to go to the new Activity.
Error:
FATAL EXCEPTION: main
Process: PID: 15534
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.realliferpgadac.thomas.adacapp/com.realliferpgadac.thomas.adacapp.Feed}: java.lang.ClassCastException: android.widget.TextView cannot be cast to android.view.ViewGroup
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ClassCastException: android.widget.TextView cannot be cast to android.view.ViewGroup
at android.app.BackStackRecord.configureTransitions(BackStackRecord.java:1244)
at android.app.BackStackRecord.beginTransition(BackStackRecord.java:978)
at android.app.BackStackRecord.run(BackStackRecord.java:707)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
at android.app.FragmentController.execPendingActions(FragmentController.java:325)
at android.app.Activity.performStart(Activity.java:6252)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Source code of the activity that crashes: (It should be a RSS Feed)
import android.os.AsyncTask;
import android.os.Bundle;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ListFragment;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import java.io.StringReader;
public class Feed extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.tvFeed, new PlaceholderFragment())
.commit();
}
}
//#Override
// public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.main, menu);
//return true;
//}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.tvFeed) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends ListFragment {
// private TextView mRssFeed;
public PlaceholderFragment() {
}
// #Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Bundle savedInstanceState) {
// View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// mRssFeed = (TextView) rootView.findViewById(R.id.rss_feed);
// return rootView;
// }
#Override
public void onStart() {
super.onStart();
new GetAndroidPitRssFeedTask().execute();
}
private String getAndroidPitRssFeed() throws IOException {
InputStream in = null;
String rssFeed = null;
try {
URL url = new URL("http://www.androidpit.com/feed/main.xml");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
in = conn.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int count; (count = in.read(buffer)) != -1; ) {
out.write(buffer, 0, count);
}
byte[] response = out.toByteArray();
rssFeed = new String(response, "UTF-8");
} finally {
if (in != null) {
in.close();
}
}
return rssFeed;
}
private class GetAndroidPitRssFeedTask extends AsyncTask<Void, Void, List<String>> {
#Override
protected List<String> doInBackground(Void... voids) {
List<String> result = null;
try {
String feed = getAndroidPitRssFeed();
result = parse(feed);
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
private List<String> parse(String rssFeed) throws XmlPullParserException, IOException {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new StringReader(rssFeed));
xpp.nextTag();
return readRss(xpp);
}
private List<String> readRss(XmlPullParser parser)
throws XmlPullParserException, IOException {
List<String> items = new ArrayList<>();
parser.require(XmlPullParser.START_TAG, null, "rss");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("channel")) {
items.addAll(readChannel(parser));
} else {
skip(parser);
}
}
return items;
}
private List<String> readChannel(XmlPullParser parser)
throws IOException, XmlPullParserException {
List<String> items = new ArrayList<>();
parser.require(XmlPullParser.START_TAG, null, "channel");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("item")) {
items.add(readItem(parser));
} else {
skip(parser);
}
}
return items;
}
private String readItem(XmlPullParser parser) throws XmlPullParserException, IOException {
String result = null;
parser.require(XmlPullParser.START_TAG, null, "item");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("title")) {
result = readTitle(parser);
} else {
skip(parser);
}
}
return result;
}
// Processes title tags in the feed.
private String readTitle(XmlPullParser parser)
throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, null, "title");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, null, "title");
return title;
}
private String readText(XmlPullParser parser)
throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
#Override
protected void onPostExecute(List<String> rssFeed) {
if (rssFeed != null) {
setListAdapter(new ArrayAdapter<>(
getActivity(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
rssFeed));
}
}
}
}
}
XML file of the activity that crashes:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.realliferpgadac.thomas.adacapp.Feed">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/tvFeed"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</ScrollView>
</RelativeLayout>
Where is the problem and how can I solve it?
I hope you can help me.
Thank you,
emt
Replace R.id.tvFeed with Framelayout's id or default id android.R.id.content.
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(android.R.id.content, new PlaceholderFragment())
.commit();
}
and remove the code from the onOptionsItemSelected() method.
if (id == R.id.tvFeed) {
return true;
}
I'm following the android xml parsing tutorial (http://developer.android.com/training/basics/network-ops/xml.html#analyze), however when stepping through it, it seems to fail at:
parser.require(XmlPullParser.START_TAG, ns, "rss");
and then ends up dropping to the finally clause. Just wondering if anyone could spot what the issue could be as I've played around with it for hours without much success.
The feed I am trying to read is: http://feeds.bbci.co.uk/news/rss.xml
Any help is greatly appreciated, please find the code below:
package com.proxama.news_bbc;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.Fragment;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.provider.DocumentsContract.Document;
public class MainActivity extends ActionBarActivity {
private static final String ns = null;
/*
* Only interested in the content of the following XML tags for each news
* item:
*
* item/media:thumbnail item/pubDate item/link item/description item/title
*/
private void skip(XmlPullParser parser) throws XmlPullParserException,
IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
public static class Entry {
public final String title;
public final String link;
public final String summary;
private Entry(String title, String summary, String link) {
this.title = title;
this.summary = summary;
this.link = link;
}
}
// Parses the contents of an entry. If it encounters a title, summary, or
// link tag, hands them off
// to their respective "read" methods for processing. Otherwise, skips the
// tag.
// Processes title tags in the feed.
private String readTitle(XmlPullParser parser) throws IOException,
XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "title");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "title");
return title;
}
// Processes link tags in the feed.
private String readLink(XmlPullParser parser) throws IOException,
XmlPullParserException {
String link = "";
parser.require(XmlPullParser.START_TAG, ns, "link");
String tag = parser.getName();
String relType = parser.getAttributeValue(null, "rel");
if (tag.equals("link")) {
if (relType.equals("alternate")) {
link = parser.getAttributeValue(null, "href");
parser.nextTag();
}
}
parser.require(XmlPullParser.END_TAG, ns, "link");
return link;
}
// Processes summary tags in the feed.
private String readSummary(XmlPullParser parser) throws IOException,
XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "summary");
String summary = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "summary");
return summary;
}
// For the tags title and summary, extracts their text values.
private String readText(XmlPullParser parser) throws IOException,
XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
private Entry readEntry(XmlPullParser parser)
throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "item");
String title = null;
String summary = null;
String link = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("title")) {
title = readTitle(parser);
} else if (name.equals("summary")) {
summary = readSummary(parser);
} else if (name.equals("link")) {
link = readLink(parser);
} else {
skip(parser);
}
}
return new Entry(title, summary, link);
}
private List readFeed(XmlPullParser parser) throws XmlPullParserException,
IOException {
List entries = new ArrayList();
String xmlContents = parser.toString();
parser.require(XmlPullParser.START_TAG, ns, "rss");
Log.d("className", "Up to here ");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// Starts by looking for the news item tag
if (name.equals("item")) {
entries.add(readEntry(parser));
} else {
skip(parser);
}
}
return entries;
}
private List parseXml(InputStream in) throws XmlPullParserException,
IOException {
try {
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(in, null);
return readFeed(parser);
} finally {
in.close();
}
}
private String downloadUrl(String myurl) throws IOException {
// TODO allow for internal storage if external is unavailable or full
File root = android.os.Environment.getExternalStorageDirectory();
String Directory = root.getAbsolutePath() + "/xmls";
String xmlFileName = "bbc_news_rss.xml";
String fullXmlPath = Directory + "/" + xmlFileName;
File dir = new File(Directory);
if (dir.exists() == false) {
dir.mkdirs();
}
/*URL url = new URL(myurl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(fullXmlPath);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();*/
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream in = conn.getInputStream();
Log.d("className", "Saved XML file to: " + fullXmlPath);
Log.d("className", "Starting to parse XML file: " + fullXmlPath);
//InputStream in = new FileInputStream(fullXmlPath);
try {
parseXml(in);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fullXmlPath;
}
// Uses AsyncTask to create a task away from the main UI thread. This task
// takes a
// URL string and uses it to create an HttpUrlConnection. Once the
// connection
// has been established, the AsyncTask downloads the contents of the webpage
// as
// an InputStream. Finally, the InputStream is converted into a string,
// which is
// displayed in the UI by the AsyncTask's onPostExecute method.
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... stringUrl) {
try {
Log.d("className", "Downloading url: " + stringUrl[0]);
return downloadUrl(stringUrl[0]);
} catch (IOException e) {
return "Unable to retrieve file.";
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
Log.d("className",
"In onpostexecute and result of downloadUrl is: " + result);
// If the file has been saved correctly, parse it.
if (result != "Unable to retrieve file.") {
Log.d("className", "Creating list view");
createList();
}
}
}
/** Pull in the XML from http://feeds.bbci.co.uk/news/rss.xml */
public void pull_xml(View view) {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// can connect so fetch XML file
Log.d("className", "Successfully connected to network!");
new DownloadWebpageTask()
.execute("http://feeds.bbci.co.uk/news/rss.xml");
} else {
// display error
Log.d("className",
"Unable to connect to network, trying to use a previously saved local xml file");
}
}
public void createList() {
setContentView(R.layout.activity_main);
// Get ListView object from XML
ListView listView = (ListView) findViewById(R.id.listView1);
// Defined Array values to show in ListView
String[] values = new String[] { "Ukraine begins 'anti-terror' action" };
// Define a new Adapter
// First parameter - Context
// Second parameter - Layout for the row
// Third parameter - ID of the TextView to which the data is written
// Forth - the Array of data
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, values);
// Assign adapter to ListView
listView.setAdapter(adapter);
}
// Original classes and methods that came by default with new android
// projects.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// retrieve the XML and create list view
pull_xml(null);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
}
Your code has several mistakes:
DownloadWebpageTask.onPostExecute: here you are trying to compare Strings with != operator. It's wrong, you'll always get false. The correct way is to use equals method:
if ("Unable to retrieve file.".equals(result)) {
Log.d("className", "Creating list view");
createList();
}
createList() method: what's the purpose of calling setContentView(R.layout.activity_main); here if you already did it at the onCreate?
pull_xml(View view) method: what's the purpose of view argument? You are not using it at this method.
parseXml method: please add parser.nextTag()
I am trying to parse the xml file:
<?xml version="1.0"?>
<root>
<command>
<word>cancel</word>
<explanation>cancel print requested with lp</explanation>
</command>
<command>
<word>cat file</word>
<explanation>Display the file</explanation>
</command>
</root>
I am using XML pull parser for this.My program is
package com.example.androidsample2;
import java.io.IOException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView myXmlContent = (TextView)findViewById(R.id.my_xml);
String stringXmlContent;
try {
stringXmlContent = getEventsFromAnXML(this);
myXmlContent.setText(stringXmlContent);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String getEventsFromAnXML(Activity activity)
throws XmlPullParserException, IOException
{
StringBuffer stringBuffer = new StringBuffer();
Resources res = activity.getResources();
XmlResourceParser xpp = res.getXml(R.xml.xmlfile);
xpp.next();
int eventType = xpp.getEventType();
String tag;
while ((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT)
{
if(XmlPullParser.START_TAG==eventType)
{
tag=xpp.getName();
//stringBuffer.append("\n"+tag);
if(tag=="word")
{
eventType=xpp.next();
stringBuffer.append("\n"+xpp.getText().toString());
}
}
}
return stringBuffer.toString();
}
}
How can i obtain the "explanation" by using "word".i.e how can i obtain "cancel print requested with lp" by using "cancel"?
The following line might work in C# but not in Java:
if(tag=="word")
Instead, write:
if (tag.equals("word"))
Update:
String word = null;
while ((eventType = xpp.next()) != XmlPullParser.END_DOCUMENT)
...
if (tag.equals("word"))
{
eventType = xpp.next();
word = xpp.getText();
}
else if (tag.equals("explanation"))
{
eventType = xpp.next();
if ("cancel".equals(word))
{
stringBuffer.append("\n" + xpp.getText());
}
}
I followed a tutorial to learn to parse the data from the gpx file (which is in my raw folder), and for some reason no data is getting parsed into the NodeList. Here is my XMLParser class
package bry.Bicker.OjaiHiking;
import java.io.IOException;
import java.io.StringReader;
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.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.util.Log;
public class XMLParser {
public Document getDomElement(String xml) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
// return DOM
return doc;
}
public String getValue(Element e, String str) {
NodeList n = e.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
public final String getElementValue(Node elem) {
Node child;
if (elem != null) {
if (elem.hasChildNodes()) {
for (child = elem.getFirstChild(); child != null; child = child
.getNextSibling()) {
if (child.getNodeType() == Node.TEXT_NODE) {
return child.getNodeValue();
}
}
}
}
return "";
}
}
Here is how I am attempting to use the class to parse the file:
public void displayPoints(MapView map, Context context) {
final String KEY_TRKPT = "trkpt";
final String KEY_LAT = "lat";
final String KEY_LON = "lon";
XMLParser parser = new XMLParser();
Document doc = parser.getDomElement(getString(R.raw.test));
NodeList n1 = doc.getElementsByTagName(KEY_TRKPT);
if (n1.getLength() > 0) {
int[] lat = new int[n1.getLength()];
int[] lon = new int[n1.getLength()];
for (int i = 0; i < n1.getLength(); i++) {
org.w3c.dom.Element e = (org.w3c.dom.Element) n1.item(i);
lat[i] = Integer.parseInt(parser.getValue(e, KEY_LAT));
lon[i] = Integer.parseInt(parser.getValue(e, KEY_LON));
}
} else {
Log.i("Debug", "XML Parsing error. No data in nodelist.");
}
}
and the GPX file was exported from the application "MyTracks."
I get no errors, but my message that states "XML Parsing error. No data in nodelist." is displayed.
There are a few useful libraries out there - including mine. See answer to this other question on StackOverflow. Basically my library provides two ways to parse you GPX file: once you obtain / create a GPXParser object (mParser in the examples below), you can then either parse directly your GPX file
Gpx parsedGpx = null;
try {
InputStream in = getAssets().open("test.gpx");
parsedGpx = mParser.parse(in);
} catch (IOException | XmlPullParserException e) {
e.printStackTrace();
}
if (parsedGpx == null) {
// error parsing track
} else {
// do something with the parsed track
}
or you can parse a remote file:
mParser.parse("http://myserver.com/track.gpx", new GpxFetchedAndParsed() {
#Override
public void onGpxFetchedAndParsed(Gpx gpx) {
if (gpx == null) {
// error parsing track
} else {
// do something with the parsed track
}
}
});
Contributions are welcome.
This open source library is currently being used in an android app, both smartphone side and smartwatch side as well
https://plus.google.com/u/0/communities/110606810455751902142
Usage example
Gpx gpx = GpxFileIo.parseIn( "SomeGeoCollection.gpx" ) ;
for (Point pt: gpx.getPoints( ) )
{
Location loc = new Location( pt.getLatitude( ), pt.getLongitude( ) ) ;
if (pt.getElevation( ) != null) loc.setElevation( pt.getElevation( ) ) ;
}
My code i use to parse HTMl is this below, and the 2nd code is how i call on it to populate an array for a simplelist.
The problem i have is it take upwards of 5 or 6 seconds to download, parse and display the data, which is far too long.
What is a way to speed up the process so its as close so instant as possible
Also, just so its clear i hard coded the url into the 2nd bit of code, once done, that will be passed in, depending on waht route, direction and stop you use.
public ArrayList<String> getStops(String URL) {
ArrayList<String> BusStop = new ArrayList<String>();
String HTML = DownloadText(URL);
String temp = null;
String temp2[] = new String[40];
Pattern p = Pattern.compile("<a class=\"ada\".*</a>", Pattern.DOTALL);
Matcher m = p.matcher(HTML);
while (m.find()) {
temp = m.group();
temp2 = temp.split("<br></td>");
}
for (int i = 0; i < temp2.length; i++) {
temp = temp2[i];
temp = temp.replaceAll("<a class=\"ada\" title=\"", "");
temp = temp.replaceAll("\".*\"", "");
temp = temp.replaceAll("\n", "");
temp = temp.replaceAll("\t", "");
temp = temp.replaceAll(",</a>", "");
temp = temp.replaceAll("</tr>.*>", "");
temp = temp.replaceAll("<td.*>", "");
temp = temp.replaceAll(">.*", "");
BusStop.add(temp);
}
return BusStop;
}
..
TransitXMLExtractor extractor;
static String baseURL5 = "http://www.ltconline.ca/webwatch/ada.aspx?r=1&d=2";
/** Populates string array with bus routes */
public String[] busStopArray() {
extractor = new TransitXMLExtractor();
String[] busStopArray = new String[31];
for (int n = 0; n < busStopArray.length; n++) {
busStopArray[n] = extractor.getStops(baseURL5).get(n);
}
return busStopArray;
}
It seems like you could speed things up by pulling the exact text you want with the regular expression and reducing the parsing loop.
public ArrayList<String> getStops(String URL) {
ArrayList<String> BusStop = new ArrayList<String>();
String HTML = DownloadText(URL);
Pattern p = Pattern.compile("<a class=\"ada\" title=\"([\\w\\s]+)\"");
Matcher m = p.matcher(HTML);
while (m.find()) {
BusStop.add(m.group(1));
}
return BusStop;
}
Also, the calling bit could just be:
public String[] busStopArray() {
extractor = new TransitXMLExtractor();
return extractor.getStops(baseURL5).toArray(new String[0]);
}
The way I have it now, it should pull the text in the title attribute from each link of class 'ada'.
EDIT: To be clear, it should actually pull the the <a class="ada" title="(whatever)", one at a time with the group(1) getting the (whatever) text for you.
EDIT 2: I updated the examples to match what I found to be working code. Also, here is the entire Activity I used to test with:
package com.kiswa.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StringBuilder sb = new StringBuilder();
for (String stop : busStopArray()) {
sb.append(stop);
}
Log.d("STRING_TEST", sb.toString());
setContentView(R.layout.main);
}
public String DownloadText() throws UnsupportedEncodingException, IOException {
Log.d("STRING_TEST", "In DownloadText");
URL url = new URL("http://www.ltconline.ca/webwatch/ada.aspx?r=1&d=2");
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
for (String line; (line = reader.readLine()) != null;) {
builder.append(line.trim());
}
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}
return builder.toString();
}
public ArrayList<String> getStops() {
Log.d("STRING_TEST", "In getStops");
ArrayList<String> BusStop = new ArrayList<String>();
String HTML = "";
try {
HTML = DownloadText();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Pattern p = Pattern.compile("<a class=\"ada\" title=\"([\\w\\s]+)\"");
Matcher m = p.matcher(HTML);
while (m.find()) {
BusStop.add(m.group(1));
}
return BusStop;
}
public String[] busStopArray() {
Log.d("STRING_TEST", "In busStopArray");
return getStops().toArray(new String[0]);
}
}