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
}
Related
I am busy with trying to get an array which i get from MSSQL to display in a table view form in my application. I have tried to google it but i cant seem to find an example of this. I have tried it but i am running into one small error.
I get the following error Cannot resolve constructor:Simpletabledata adapter[package.mainactivity, package.itemarray]
Here is my mainactivy.java class:
public class MainActivity extends AppCompatActivity {
static String[] spaceProbeHeaders={"Name"};
private ArrayList<ClassListItems> itemArrayList; //List items Array
private MyAppAdapter myAppAdapter; //Array Adapter
final TableView<String[]> tableView = (TableView<String[]>) findViewById(R.id.tableView);
private boolean success = false; // boolean
Connection conn; // Connection Class Initialization
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tableView.setHeaderBackgroundColor(Color.parseColor("#777777"));
tableView.setHeaderAdapter(new SimpleTableHeaderAdapter(this,spaceProbeHeaders));
tableView.setColumnCount(4);
itemArrayList = new ArrayList<ClassListItems>(); // Arraylist Initialization
// Calling Async Task
SyncData orderData = new SyncData();
orderData.execute("");
}
// Async Task has three overrided methods,
private class SyncData extends AsyncTask<String, String, String>
{
String msg = "Internet/DB_Credentials/Windows_FireWall_TurnOn Error, See Android Monitor in the bottom For details!";
ProgressDialog progress;
#Override
protected void onPreExecute() //Starts the progress dailog
{
progress = ProgressDialog.show(MainActivity.this, "Synchronising",
"Tableview Loading! Please Wait...", true);
}
#Override
protected String doInBackground(String... strings) // Connect to the database, write query and add items to array list
{
try
{
ConnectionClass conStr=new ConnectionClass();
conn =conStr.connectionclass();
//Connection Object
if (conn == null)
{
success = false;
}
else {
// Change below query according to your own database.
String query = "SELECT customer_first_name FROM cc_customer";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
if (rs != null) // if resultset not null, I add items to itemArraylist using class created
{
while (rs.next())
{
try {
itemArrayList.add(new ClassListItems(rs.getString("customer_first_name")));
} catch (Exception ex) {
ex.printStackTrace();
}
}
msg = "Found";
success = true;
} else {
msg = "No Data found!";
success = false;
}
}
} catch (Exception e)
{
e.printStackTrace();
Writer writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
msg = writer.toString();
success = false;
}
return msg;
}
#Override
protected void onPostExecute(String msg) // disimissing progress dialoge, showing error and setting up my listview
{
progress.dismiss();
Toast.makeText(MainActivity.this, msg + "", Toast.LENGTH_LONG).show();
if (success == false)
{
}
else {
try {
//myAppAdapter = new MyAppAdapter(itemArrayList, MainActivity.this);
tableView.setDataAdapter(new SimpleTableDataAdapter(MainActivity.this,itemArrayList ));
} catch (Exception ex)
{
}
}
}
}
and here is my classlist.java file:
public class ClassListItems
{
public String name; //Name
public ClassListItems(String name)
{
this.name = name;
}
public String getName() {
return name;
}
Update
N.B: OP is using SortableTableView Library.
You need to import the following to solve Cannot resolve constructor:SimpleTableDataAdapter-
import de.codecrafters.tableview.toolkit.SimpleTableDataAdapter;
Original
Do you have SimpleTableDataAdapter class in your project? It seems it can't find the class so it is not in the same package. If it is in different package, you need to import it.
And on a different note, your .java file names should match the class name
And on another different note, have you tested that itemArrayList is actually populating? For Android-MSSQL, here is a tutorial pointer -
https://parallelcodes.com/connect-android-to-ms-sql-database-2/
There are many tutorials if you google it.
I'm developing a wallpaper app using mongodb. I'm retrieving data from database and displaying it on my recyclerView by the help of a data-model class without any problem. Also I'm using swipe refresh layout to allow user for refreshing the recyclerView for new data.
But now the problem is how can I avoid data repetition and show only new posts to the user. I meant if there are 5 pics are there in my db in my first query I'll get those 5 so when the user will refresh the layout again the recyclerView's item is increased to 10 and I wanna avoid this I want to show them new pics only when the posts in db will be increased to 6 or more.
I think this data avoid concept is also used in social media apps. but for this context I wonder what I have to do?
Data model class:
public class TimelineData {
private String type, time, img_link;
public TimelineData(String type, String time, String img_link) {
this.type = type;//type means what type of wallpaper
this.time = time;
this.img_link = img_link;
}
public String getType() {
return type;
}
public String getTime() {
return time;
}
public String getImg_link() {
return img_link;
}
}
Adding Data to recyclerview:
private List<TimelineData> timelineDataList = new ArrayList<>();
public void onCreateView() {
recyclerview.setItemViewCacheSize(20);
recyclerview.setDrawingCacheEnabled(true);
recyclerview.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
recyclerview.setLayoutManager(new LinearLayoutManager(ctx));
//Setting Adapter
adapter=new CustomRecyclerViewAdapter(timelineDataList);
recyclerview.setAdapter(adapter);
}
#Override
public void onStart() {
super.onStart();
// Fetching data from server
socket.disconnect();
socket.connect();
//Getting Data from server
JSONObject obj=new JSONObject();
try {
obj.put("timeline_posts","all");
socket.emit("data",obj);
} catch (JSONException e) {
e.printStackTrace();
}
}
void addTimelineData(String type,String time,String img_link) {
timelineDataList.add(new TimelineData(type,time,img_link));
adapter.notifyDataSetChanged();
}
private Emitter.Listener handlePosts = new Emitter.Listener() {
#Override
public void call(final Object... args){
try {
JSONArray jsonArray=(JSONArray)args[0];
for(int i=0;i<jsonArray.length();i++){
try {
JSONObject ob=jsonArray.getJSONObject(i);
post_type=ob.getString("post_type");
post_time=ob.getString("time");
post_link=ob.getString("img_link");
addTimelineData(post_type,post_time,post_link);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
Log.e("error",e.toString());
}
}
};
You can try cleaning the data source whenever you get new data, that way you'll always reinsert the complete dataset, if you have new data it will be inserted with the old one and you don't have to worry about repeated data in the mobile app, only in the server.
private List<TimelineData> timelineDataList=new ArrayList<>() ;
public void onCreateView(){
recyclerview.setLayoutManager(new LinearLayoutManager(ctx));
//Setting Adapter
adapter=new CustomRecyclerViewAdapter(timelineDataList);
recyclerview.setAdapter(adapter);
}
#Override
public void onStart() {
super.onStart();
// Fetching data from server
socket.disconnect();
socket.connect();
//Getting Data from server
JSONObject obj=new JSONObject();
try {
obj.put("timeline_posts","all");
socket.emit("data",obj);
} catch (JSONException e) {
e.printStackTrace();
}
}
void addTimelineData(String type,String time,String img_link){
boolean isRepeated = false;
for(TimelineData data : timelineDataList){
if(data.getTime().equals(time)){
isRepeated = true;
}
}
if(!isRepeated){
timelineDataList.add(new TimelineData(type,time,img_link));
}
adapter.notifyDataSetChanged();
}
private Emitter.Listener handlePosts = new Emitter.Listener(){
#Override
public void call(final Object... args){
try {
JSONArray jsonArray=(JSONArray)args[0];
timelineDataList.clear(); //clear data before inserting new one
for(int i=0;i<jsonArray.length();i++){
try {
JSONObject ob=jsonArray.getJSONObject(i);
post_type=ob.getString("post_type");
post_time=ob.getString("time");
post_link=ob.getString("img_link");
addTimelineData(post_type,post_time,post_link);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
Log.e("error",e.toString());
}
}
};
before you add new elements to the wallpaper list, check to see if an object with that id exist in the list. if it does, skip it, else add it.
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
}
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.
I have a problem : I use a web service to return some values , but some times some problems face the web services , and when I want to display them my app crashes , so I want to make sure that if there is nothing to show then return just empty space , and I use it on JSON , there is a part of my code if someone can help me ,
public static Article parseArticle(JSONObject jsonArticle) {
Article article = new Article();
try {
article.setTitle(ArabicUtilities.reshape(Html.fromHtml(jsonArticle.getString("title")).toString()));
article.setExcerpt(ArabicUtilities.reshape(Html.fromHtml(jsonArticle.getString("excerpt")).toString()));
article.setContent(ArabicUtilities.reshape(Html.fromHtml(jsonArticle.getString("content")).toString()));
article.setDate(jsonArticle.getString("date"));
return article;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
private void loadinfo() {
{
programs = JSONParser.parseProgram(savedData);
txt1.setText(article.get(1).getTitle());
txt2.setText(article.get(0).getTitle());
txt3.setText(article.get(1).excerpt());
txt4.setText(article.get(0).excerpt());
txt5.setText(article.get(1).content());
txt6.setText(article.get(0).content());
txt7.setText(article.get(1).date());
txt8.setText(article.get(0).date());
}
this is what happened when i try to have information it give error on
txt1.setText(article.get(1).getTitle());
that there is no values
If I have not misunderstood you instead of jsonArticle.getString you can use jsonArticle.optString. It will return an empty String if the json does not contain that key.
String mString = jsonArticle.optString("title");
article.setTitle(ArabicUtilities.reshape(Html.fromHtml(mString).toString()));
mString = jsonArticle.optString("excerpt");
article.setExcerpt(ArabicUtilities.reshape(Html.fromHtml(mString).toString()));
mString = jsonArticle.optString("content");
article.setContent(ArabicUtilities.reshape(Html.fromHtml(mString).toString()));
mString = jsonArticle.optString("date");
article.setDate(mString);
here the doc for optString()
EDIT
public static Article parseArticle(JSONObject jsonArticle) {
Article article = new Article();
try {
String mString = jsonArticle.optString("title");
article.setTitle(ArabicUtilities.reshape(Html.fromHtml(mString).toString()));
mString = jsonArticle.optString("excerpt");
article.setExcerpt(ArabicUtilities.reshape(Html.fromHtml(mString).toString()));
mString = jsonArticle.optString("content");
article.setContent(ArabicUtilities.reshape(Html.fromHtml(mString).toString()));
mString = jsonArticle.optString("date");
article.setDate(mString);
} catch (JSONException e) {
e.printStackTrace();
}
return article;
}
public static Article parseArticle(JSONObject jsonArticle) {
Article article = new Article();
if(null!=jsonArticle){
try {
/*your code */
}else{
article.setTitle(ArabicUtilities.reshape("");
article.setExcerpt(ArabicUtilities.reshape("");
article.setContent(ArabicUtilities.reshape("");
article.setDate("");
return article;
}
}