Parsing XML in android, but not the attributes - android

I'm trying to parse a really simple XML in my android app, for example:
<data>
<section id="123">bla</section>
<area>blabla</area>
</data>
But in every example I find I see how to extract the data in the attribute (id being 123) when what I need to extract is the data displayed - "bla" and "blabla".
How do I do that using SAXParser?

this tutorial respond to exactly what you want hope you gonna enjoy
See how The characters method in the parser handler takes care of extreacting an element's text value

The characters method in the parser handler takes care of an element's text value.

You need to override the characters method.

Well, writing parsers by hand is of course fun & error-prone, I'd however recommend using a framework - even a simple one like the built in android.sax package.
Using the StartElementListener (if you want the attributes at all that is) & EndTextListener (captures the body text of the element):
class Section implements StartElementListener, EndTextElementListener {
String mValue;
String mId;
#Override
public void end(String body) {
mValue = body;
}
#Override
public void start(Attributes attributes) {
mId = attributes.getValue("", "id");
}
}
Listeners of these types are attached to Elements derived from a RootElement, like so:
Section section = new Section();
RootElement data = new RootElement("data");
// Use "requireChild" if a "section" is required as a child of "data".
Element s = data.getChild("section");
s.setStartElementListener(section);
s.setEndTextElementListener(section);
try {
Xml.parse(xml, data.getContentHandler());
} catch (SAXException e) {
}
Basically, this helps you build content handlers for SAX that cares about the hierarchy and keeps track of what element you are parsing easily. Short & nifty code also I guess.

Related

Using Strings from resource "R.String" on layer presenter MVP

On MVP pattern, i have string with dynamic value %
Example:
<string name="hello">%s hello</string>
and i need set this text with "my name" on my textview, how i will do this witout reference direct a R.String on my presenter layer.
public void onItemClicked(String name) {
if (mainView != null) {
//HOW use R.string.hello from Strings here? [presenter layer]
mainView.showMessage(String.format("%s hello", name));
}
}
On MVP pattern i cant have any reference an Android class in presenter layer, i dont have any context in this class, but i need use R.string.hello, because translate, how i can take this witouth ruins this MVP pattern
Quick answer: you don't
You structure your code so your view method is:
#Override
public void showMessage(String name){
if (mTextView != null){
mTextView.setText(String.format(getString(R.string.hello), name));
}
}
Then your presenter code is:
public void onItemClicked(String name) {
if (mainView != null) {
mainView.showMessage(name);
}
}
MVP is all about clean testable code, in this case all you want to be testing within your presenter is that the presenter passes the correct name to the view. You don't need to be testing String.format() or getting strings from resources (other developers have already done this, ie. the Android devs). I suggest maybe reading a bit deeper into why MVP will benefit your project
There is an overloaded version of getString() which takes varargs for formatting.

How do I correctly format this gson.fromJson call?

My array is a list of events and I need to intialize each event with its information from my JSON file. I created this simple setup based on what I found on other answers here using GSON but I'm super confused on how the gson.fromJSON call works
I have 3 variables in Event that I want to retrieve from the JSON file - start date, end date, and summary. Does fromJSON automatically assign them from the JSON to the their values in Event?
this is what my json file looks like:
[
{
"dtstart": "10/31/2015",
"dtend": "10/31/2015",
"summary": "Halloween"
},
.....
]
there are about half a dozen more of those such events.
This is my code in my Main java file:
public class MainActivity extends AppCompatActivity {
Event[] mobileArray;
Gson gson = new Gson();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("academiccalendar.json"));
} catch (FileNotFoundException e){
e.printStackTrace();
}
mobileArray = gson.fromJson(br, Event[].class);
And this is my event class:
public class Event {
private String dtsart;
private String dtend;
private String summary;
I know this must make me look like a complete fool. But I can't wrap my head around how to turn that JSON file into an array of events. Could someone please point me in the right direction? I've tried a lot of other methods on StackOverflow and elsewhere but none seem right for my situation
EDIT: Removed the loop I had for mobileArray with the line Gil posted. IMPORTANT to future people reading this message - fromGSON was NOT initializing the same named variables in my Event class and I figured out it was because they were set to private and I was trying to assign them from my main activity class. I had to change to public
Why do you need that for loop ?
Did you try this line of code:
mobileArray = gson.fromJson(br, Event[].class);
try to get the whole array at once, instead of one object at a time.
Also, what is the error that you get when trying to do so?
And for your question about fromJson, the answer is yes, it assign them automatically if the variables names are the same in the POJO and in the JSON file.

JSONObject as class attribute storage/retrieval

In android, I'm using model classes with methods to handle the data manipulation. My data is brought in from webservices as json. I'm contemplating the possibility of using JSONObjects to store the values of class level attributes. But, I don't know of a way to use the JSONObj as the "holder" variable and create access methods. I don't want to predetermine these methods, as jsonRepository should hold the values, not always known at design time
For example, I'd like to have:
public class User {
private JSONObject jsonAttributes;
public User(String json) {
this.jsonAttributes= new JSONObject(json);
}
[IMPLICIT attribute access methods]
public string Prop1() returns jsonAttributes.getString("prop1");
public string Prop1(String newProp1) returns jsonAttributes.putString("prop1",newProp1);
public string Prop2() returns jsonRepository.getString("id");
public string Prop2(String newProp2) returns jsonAttributes.putString("prop2",newProp2);
....
from outside this class then, I would access the attributes simply...
User myUser = new User(someValidJson);
String myString = myUser.Prop1
Misguided? If not, how does one manage implicit property setting/getting?
As was mentioned in the comment above, why not create your user class, with all of the relevant memeber variables, and simply parse your JSON data in order to populate the ionformation in your user class.
There are a lot of ways you can do this, but I would consider using the builder pattern, as it is flexible, which could be useful if your JSON data changes in the future.

How to parse a regular String to an XML file

What I'm trying to do is to parse an object into a String, and then , parse it into an XML so any other language can translate it.
Figure out this object:
public class DatosPac
{
private String nombre;
private String apellidos;
private String dni;
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getApellidos() {
return apellidos;
}
public void setApellidos(String apellidos) {
this.apellidos = apellidos;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
}
What I want to do is, parse it into a common XML between Android and .Net so both languages can translate the same object. The way to communicate both languages will be using Web Services, so the Web Service will receive a String, transalte it into the object and then use the information. Bidirectionally. I mean, Android will be able to receive an object parsed from .Net, and .Net will be able to receive the same object from Android. To be able to do this, I think I need to convert them into the same XML, but I don't know how to do it in Android.
Thanks in advance.
There are several XML serializing and de-serializing libraries available for Android. And I am sure the same's the case with .NET.
You set up your objects as POJOs and with a few annotations, you can serialize/deserialize in a few lines of code. In the Android world, I personally prefer Simple, but there are various other libraries available.
A more compact, (and more efficient, in terms of parsing) data representation format is JSON. There are multiple libraries available for parsing and constructing JSON too. My preferred one for Android is Gson.
EDIT: I believe I was a bit too quick! I didn't notice the android tag and assumed a .net context. Still, one bit stands: You probably want to serialize, not to "parse" the object, into XML.

Android: Programmatically iterate through Resource ids

I want to be able to iterate through all of the fields in the generated R file.
Something like:
for(int id : R.id.getAllFields()){
//Do something with id, like create a view for each image
}
I've tried reflection, but I can't seem to load a specific inner class that's contained inside the R class. So, for example, this wouldn't work for me:
Class c = Class.forName("packageName.R.id")
I can reflect on the R class itself, but I need the fields within the id class.
I also tried looking through the Resources class, but couldn't find anything there. In that case, it seems you can take a resourceID and get the string name of that id, or take a string name and get the corresponding resourceID. I couldn't find anything like:
int[] Resources.getAllResourceIDs()
Maybe I'm going about this wrong. Or maybe I shouldn't fight typing them all in by hand, e.g.:
int[] myIds = {R.id.firstResource, R.id.secondResource}
This approach has the downside of not being as flexible when working with my UI designer. Whenever he adds a new resource to the XML file, I'll have to update the code. Obviously not too painful, but it would still be nice to have and it seems like it should be doable.
EDIT:
The answer below about ViewGroup.getChildCount()/ViewGroup.getChildAt() works fine. But, I also had to find a way to instantiate my XML ViewGroup/Layout. To do that, try something like:
LayoutInflater li = MyActivity.getLayoutInflater();
ViewGroup vg = (ViewGroup) li.inflate(R.layout.main, null);
I found that "Class.forName(getPackageName()+".R$string");" can give you access to the string resources and should work for id, drawable, exc as well.
I then use the class found like this:
import java.lang.reflect.Field;
import android.util.Log;
public class ResourceUtil {
/**
* Finds the resource ID for the current application's resources.
* #param Rclass Resource class to find resource in.
* Example: R.string.class, R.layout.class, R.drawable.class
* #param name Name of the resource to search for.
* #return The id of the resource or -1 if not found.
*/
public static int getResourceByName(Class<?> Rclass, String name) {
int id = -1;
try {
if (Rclass != null) {
final Field field = Rclass.getField(name);
if (field != null)
id = field.getInt(null);
}
} catch (final Exception e) {
Log.e("GET_RESOURCE_BY_NAME: ", e.toString());
e.printStackTrace();
}
return id;
}
}
Your reply to my comment helped me get a better idea of what you're trying to do.
You can probably use ViewGroup#getChildAt and ViewGroup#getChildCount to loop through various ViewGroups in your view hierarchy and perform instanceof checks on the returned Views. Then you can do whatever you want depending on the type of the child views and where they are in your hierarchy.
You can use reflection on an inner class, but the syntax is packagename.R$id. Note that reflection can be very slow and you should REALLY avoid using it.

Categories

Resources