I'm having trouble parsing and showing information from a very simple xml file.
First of all, I'm storing the xml file in the res/xml folder. In the folder I have an xml file named jokes.xml, the content of the file is the following:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<joke>This is a good joke.</joke>
<joke>This is a very nice good great joke.</joke>
<joke>Oh Yeah!</joke>
</resources>
I want to parse this file, store all the jokes into an arraylist and the get a random one to show. My code is the following:
public class MainActivity extends Activity {
private TextView texto;
private int i = 0;
private String[] arrayJokes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
texto = (TextView) findViewById(R.id.textView1);
XmlResourceParser joke = getResources().getXml(R.xml.jokes);
try {
while( joke.getEventType() != XmlResourceParser.END_DOCUMENT ){
if( joke.getEventType() == XmlResourceParser.START_TAG ){
String s = joke.getName();
if( s.equals("joke")){
arrayJokes[i] = joke.getAttributeValue(null, "joke");
i++;
}
}
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//takes random id from the array
Random generator = new Random();
int rnd = generator.nextInt(arrayJokes.length);
String j = arrayJokes[rnd];
texto.setText(j);
}
}
The problem is that I only get a blank page. Any idea on what I'm doing wrong?
Thanks in advance,
Cláudio
you can parse your joke items like this:
private ArrayList<String> parseJokes() {
ArrayList<String> jokes = new ArrayList<String>();
XmlResourceParser parser = getResources().getXml(R.xml.jokes);
try {
int eventType=parser.getEventType();
while (eventType!=XmlPullParser.END_DOCUMENT) {
if(eventType==XmlPullParser.START_TAG){
if (parser.getName().equals("joke")) {
jokes.add(parser.nextText());
}
}
eventType= parser.next();
}
} catch (XmlPullParserException | IOException e) {
Log.e("XmlPullParserException", e.toString());
}
parser.close();
return jokes;
}
the main idea is to advance the parser across the document using the next() method.
Related
I have an Android setup that has a resource file that refers to a single layout from a choice of two.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<resources>
<item name="another_resource_id" type="layout">#layout/some_layout</item>
</resources>
or
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<resources>
<item name="another_resource_id" type="layout">#layout/some_layout2</item>
</resources>
This produces the R.layout
public static final class layout {
...
public static final int another_resource_id=0x7f030000;
public static final int some_layout=0x7f030001;
public static final int some_layout2=0x7f030002;
...
}
So the issue is that from the code I want to be able to tell which layout the another_resource_id resource identifier refers to.
I'll answer my question: Seems there is no straight forward way to tell the root view for a layout EXCEPT to dig down and get the original XML for the layout. Comparing the two is how I am able to tell if they are the same view. Kind of the long way around, but there it is. The following code just compares the addition of the resouce id for the underlying elements. Obviously you could put a lot more complex logic in.
try {
XmlResourceParser xrp = ctx.getResources().getLayout(id);
int eventType;
xrp.next();
String resourceIds = "";
do {
eventType = xrp.nextToken();
if (eventType == XmlPullParser.START_TAG) {
int attrs = xrp.getAttributeCount();
if (attrs > 0) {
for (int i = 0; i < attrs; i++) {
if (xrp.getAttributeName(i).compareTo("id") == 0) {
resourceIds += xrp.getAttributeValue(i);
}
}
}
}
} while (eventType != XmlPullParser.END_DOCUMENT);
returnVal = resourceIds.hashCode();
} catch (XmlPullParserException e) {
// e.printStackTrace();
} catch (FileNotFoundException e) {
// e.printStackTrace();
} catch (IOException e) {
// e.printStackTrace();
} catch (Resources.NotFoundException e) {
// e.printStackTrace();
}
I have list of web pages(over 100) with I have to vistit and collect data from.
I decided to save the html from all of them to one file, and then use Jsoup to find the interesting data.
But problem is to I do not know how to run 100 threads, and save the responses into one file, any ideas?
maybe it's not a masterpiece, but it works, and I wanted to make it as simple as possible.
ArrayList<String> links = new ArrayList<>();
Elements myDiv;
private void saveDetails() throws IOException {
if(repeat < links.size()){
repeat++;
textView.setText(String.valueOf(repeat));
saveFile(myDiv.toString());
myDiv = null;
getDetails(links.get(repeat));
}else {
textView.setText("finished");
}
}
private void getDetails(String urlStr) {
final String detailsUrl = urlStr;
new Thread() {
#Override
public void run() {
Message msg = Message.obtain();
try {
Document doc = Jsoup.connect(detailsUrl).get();
myDiv = doc.select(".exhibitor-contact");
} catch (IOException e1) {
e1.printStackTrace();
}
detailsHandler.sendMessage(msg);
}
}.start();
}
private Handler detailsHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
try {
saveDetails();
} catch (IOException e) {
e.printStackTrace();
}
}
};
You don't need to save all of them in a file and then process them. You can gather information one by one. It is my suggestion:
arrayList urls = {100 site-url}; //in correct syntax
Document doc = null;
for (String url : urls) {
doc = Jsoup.connect(url).get();
//now proccess doc.toString as you want(in regular expression for example)
//save your desired information
}
In the following code,i am saving the three values fun_id,fun_logo,fun_req with the help of another class Use.In the code an arraylist is returned,now i want to retrieve the fun_id,fun_logo,fun_req.I want to add fun_logo into imagearray.I would like to know how to use the Class Use for retreving data.I am learning currently so only small idea bout android.
ArrayList<Use> stringArrayList = null;
ArrayList<Use> res = null;
ArrayList<String> linklist = null;
String getdetailsurl;
String link [];
String[] ar;
Use[] getalldet;
public String imagearray[];
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Getdetailsfromweb().execute();
list=(ListView)findViewById(R.id.listView1);
// adapter=new myadpter(this, imagearray);
list.setAdapter(adapter);
}
public class Getdetailsfromweb extends AsyncTask<String,Void,String>
{
String result = "";
#Override
protected String doInBackground(String... params) {
getdetailsurl=Webcall.getdet();
if(getdetailsurl!=null)
{
result = "Success";
}
else
{
result = "Failure";
}
return result;
}
#Override
protected void onPostExecute(String result) {
res = new ArrayList<Use>();
try {
if (result.contentEquals("Success"))
{
res=passdetails();
System.out.println("lsize is " + res.size());
for(int i=0;i<res.size();i++)
{
// To retreive value what should i do here
imagearray[i]=obj.funlogo;
System.out.println("logo is " + imagearray[i]);
}
}
else
{
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
public ArrayList<Use> passdetails()
{
JSONArray array = null;
stringArrayList = new ArrayList<Use>();
linklist= new ArrayList<String>();
Use usee;
try {
array = new JSONArray(getdetailsurl);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i = 0;i <array.length() ;i++ )
{
String fun_id= null;
String fun_logo= null;
String fun_req = null;
try {
fun_id = array.getJSONObject(i).getString("up_id");
System.out.println("up_id is " + fun_id);
fun_logo=array.getJSONObject(i).getString("logo");
System.out.println("logo is " + fun_logo);
fun_req=array.getJSONObject(i).getString("requirements");
System.out.println("req is " + fun_req);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
usee=new Use();
usee.funid=fun_id;
System.out.println("fun is " + usee.funid);
usee.funlogo=fun_logo;
System.out.println("fun is " + usee.funlogo);
usee.funreq=fun_req;
System.out.println("fun is " + usee.funreq);
linklist.add(fun_logo);
stringArrayList.add(usee);
}
return stringArrayList;
}
}
Use.java
public class Use {
public static String funid;
public String funlogo;
public String funreq;
}
I would like to know how to use the Class Use for retrieving data
All fields are public in Use and res is ArrayList of object of Use class. access values from each object as :
for(int i=0;i<res.size();i++)
Use useObj=res.get(i);
String funlogo=useObj.funlogo;
String funreq=useObj.funreq;
...
}
Define a Use class with getter and setter methods.
Define a method getFunLogos() in Use class which would return the image array of all the fun logos. Access this method from wherever you want.
protected String[] getFunLogos(ArrayList<Use> listFunLogos) {
for(int i=0;i<res.size();i++)
{
// To retreive value what should i do here
imagearray[i]=obj.funlogo;
System.out.println("logo is " + imagearray[i]);
}
}
I want to add fun_logo into imagearray
//linklist : as you are adding fun_log in it
imagearray=new String[linklist.size()];
linklist.toArray(imageArray);
I am working on android application. In my app I got the xml data response from server and stored it in a string. Now I need to get each value of that xml and display in a dropdown. How can I do that. Please help me with this. Will be really thankful.
My xml data:
<?xml version="1.0" encoding="utf-8"?>
<root>
<status>first<status>
<description>very good</description>
<Firstnames>
<name>CoderzHeaven</name>
<name>Android</name>
<name>iphone</name>
</Firstnames>
<SecondNames>
<name>Google</name>
<name>Android</name>
</SecondNames>
</root>
I am getting the above mentioned xml data from server. Now I need to display that in listview. How can I get those values using xmlparser. I tried with different examples but it didnt work for me.
You will need to create an extra class and parametrize your adapter with objects of this class, an example data model would look like:
public class DataClass {
private String status, description;
private ArrayList<String> fnames, lnames;
public DataClass() {
fnames = new ArrayList<String>();
lnames = new ArrayList<String>();
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ArrayList<String> getFnames() {
return fnames;
}
public ArrayList<String> getLnames() {
return lnames;
}
}
As for the XML parser, there are literally tons of examples, you're definitely in advantage if you can use search. Just to give you a staring point, tutorials one, two, three, four.
If you experience problems, post your efforts and the code that didn't work, what have you tried and so on. Then you'll get help, otherwise nobody on SO is going to write code for you. https://stackoverflow.com/help/how-to-ask
Here's how you can do it if the xml is inside of your apps assets folder.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InputStream input = null;
try {
input = getApplicationContext().getAssets().open("data.xml");
} catch (IOException e) {
e.printStackTrace();
}
DocumentBuilder builder = null;
try {
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
Document doc = null;
if (builder == null) {
Log.e("TAG", "Builder is empty.");
return;
}
try {
doc = builder.parse(input);
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (doc == null) {
Log.e("TAG", "Document is empty.");
return;
}
// Get Firstnames element
Element firstNames = (Element) doc.getElementsByTagName("Firstnames").item(0);
// Get name nodes from Firstnames
NodeList nameNodes = firstNames.getElementsByTagName("name");
// Get count of names inside of Firstnames
int cChildren = nameNodes.getLength();
List<String> names = new ArrayList<String>(cChildren);
for (int i=0; i<cChildren; i++) {
names.add(nameNodes.item(i).getTextContent());
Log.d("TAG","Name: "+names.get(i));
}
// Do same with SecondNames
}
I load dynamically the string of my autocomplete with JSON objects, but the list appears only in the next character; How can I make my list appear exactly after the loading?
This process is called from a onTextChanged event. I tried to force display with showDropDown() but didn't work!!!
Any help?
public class HttpConnectionApiActivity extends Activity implements HttpListner, TextWatcher {
.....
AutoCompleteTextView from_txt;
List<String> country_List;
ArrayAdapter<String> adapter;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
from_txt = (AutoCompleteTextView) findViewById(R.id.from_txt);
//from_txt.setThreshold(1);
prepareCountryList();
from_txt.addTextChangedListener( this);
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,country_List);
from_txt.setAdapter(adapter);
}
....
public void notifyHTTPRespons(final HttpHandler http) {
public void run() {
String result = http.getResponse();
try {
adapter.clear();
for (int i = 0; i < results_Array.length(); i++) {
JSONObject row = results_Array.getJSONObject(i);
String name=row.getString("name");
adapter.add(name);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I could display the dropdown list by adding these 2 lines :
It's very simple hack by resetting text when you get updated data.
try {
adapter.clear();
for (int i = 0; i < results_Array.length(); i++) {
JSONObject row = results_Array.getJSONObject(i);
String name=row.getString("name");
adapter.add(name);
}
//____________________
adapter.notifyDataSetChanged();
from_txt.setText(from_txt.getText());
//____________________
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}