How to parse an XML file and create objects using found values? - android

I would like to parse an XML file using Java. I found some tutorials online but no one tells about parsing subtags and using them as objects' attributes.
I tried to use the code found here.
But it doesn't show how to treat tags that are inside other tags. Let me show you an example:
<lotto>
<cig>Z9E1CD9F58</cig>
<strutturaProponente>
<codiceFiscaleProp>00222010654</codiceFiscaleProp>
<denominazione>COMUNE DI PERDIFUMO</denominazione>
</strutturaProponente>
</lotto>
lotto is my main tag, which contains all the data I need. In my code, I created a class called in the same way. Its attributes are the same as the tags contained in the main one (cig, strutturaProponente,...).
I would like strutturaProponente to become a class. I don't know how to parse tags which are inside of tag strutturaProponente as well as the tag cig.
Thank you for your patience and consideration.

Well, let me see if I understood. Would you like the representantion in code of XML, I believe that class would be like something this.
public class Loto
{
private String cig;
public String getCig()
{
return cig;
}
public void setCig(String value){
cig = value;
}
}
public class StrutturaProponente
{
private int codiceFiscaleProp;
private string denominazione;
public int getCodiceFiscaleProp()
{
return cig;
}
public void setCodiceFiscaleProp(int value){
codiceFiscaleProp = value;
}
public String getDenominazione()
{
return denominazione;
}
public void setDenominazione(String value){
denominazione = value;
}
}
I hope have helped.

Related

how to handle different json result

I want to get information from baidu music web api. I use below tow link:
http://openapi.baidu.com/rest/2.0/music/billboard/billlist?page_size=50&timestamp=2016-09-22+18%3A47%3A54&sign=b2e34bd4b6c19a065d5a7e49e591a41b&session_key=9mzdDcHtDENrxP3Spvk7ZFbNHNijT8l8fN%2BfI%2Fe3U5rh3U5g%2FDVvjZyqB48aJaYO5qaqw4JbugF79hgAQ%2FGBIixUSuaP&type=21&page_no=1
http://openapi.baidu.com/rest/2.0/music/billboard/billlist?page_size=50&timestamp=2016-09-26+17%3A42%3A18&sign=62cc904c8ff2817280f699a4bd4b6496&session_key=9mzdDcHtDENrxP3Spvk7ZFbNHNijT8l8fN%2BfI%2Fe3U5rh3U5g%2FDVvjZyqB48aJaYO5qaqw4JbugF79hgAQ%2FGBIixUSuaP&type=23&page_no=1
only type is different. one is 23 and another is 21. For return jason: one is billboard21, another is billboard23. If I want to use retrofit2 to accessa api and parse return jason, should I define two different java class to handler this two different return? In face, there is about 17 type, how can I handle this case if don't want to create 17 java classes?
my access api is:
#GET("/rest/2.0/music/billboard/billlist")
Call<BaiduBillListContainer> getBillList(#Query("timestamp") String timestamp,
#Query("type") String type,
#Query("sign") String sign,
#Query("session_key") String sessionkey,
#Query("page_size") String pagesize,
#Query("page_no") String pageno);
BaiduBillListContainer.java define:
public class BaiduBillListContainer implements Serializable {
BaiduBillList billboard21;
public BaiduBillList getBillBoardInfo() {
return billboard21;
}
public void setBillBoardInfo(BaiduBillList billBoardInfo) {
this.billboard21 = billBoardInfo;
}
}
it cannot used to get billboard23 return. Any one can help me about this question? thanks very much.
Try this:
public class BaiduBillListContainer implements Serializable {
Map<String,BaiduBillList> billboard;
public Map<String,BaiduBillList> getBillBoardInfo() {
return billboard;
}
public void setBillBoardInfo(Map<String,BaiduBillList> billBoardInfo) {
this.billboard= billBoardInfo;
}
}
Then call billboard from map like:
Map<String,BaiduBillList> getBBData=response.body();
BaiduBillList receivedBBList=getBBData.values().toArray()[0]

Custom object two-way databinding android:text

I've created myself some simple class for validating fields through two-way databinding.
public class ValidatedField extends BaseObservable{
private String mValue;
#Bindable
public String getValue()
{
return mValue;
}
public void setValue(String value)
{
if(Objects.equals(value, mValue)) return;
mValue = value;
notifyPropertyChanged(BR.value);
}
...
}
In ViewModel I setup this class and bind it to view as usual in databinding
(all binding actually works so no error here).
public ValidatedField phoneNumber = new ValidatedField();
In layout, I have view with android:text property and I setup:
<EditText
android:text="#={viewModel.phoneNumber.value}"
/>
And everything works like a charm.
And my question is: is it possible to skip '.value' from layout so that it looks like this:
<EditText
android:text="#={viewModel.phoneNumber}"
/>
I could make it work if it was one way binding e.g. through binding conversion like this:
#BindingConversion
public static String convertValidatedFieldToString(ValidatedField field){
return field.getValue();
}
But I'm not able to set new value to existing ValidatedField.
I've tried to use #InverseBindingAdapter but that's without luck because it would create every time new object and not just updated value of existing one.
#InverseBindingAdapter(attribute = "android:text")
public static ValidatedField convertStringToValidatedField(TextView view)
{
return new ValidatedField(view.getText().toString());
}
Thank you!
Edit:
I should've said that I have other #Bindable fields in the class. e.g:
#Bindable
public boolean getIsError()
{
return mIsError;
}
It seems to me that you could've just extend ObservableField<String> and then override its set method.
so like:
public class ValidatedField extends ObservableField<String> {
#Override
public void set(String value) {
if (get().equals(value))
return;
super.set(value);
}
}
Databindings is lacking an InverseBindingConversion. At the moment it's not working like you intent to use it.
So you have to write #={viewModel.phoneNumber.value} anytime.

Translating iOS Enums to Android

I'm busy trying to translate some iOS code to Android code. The iOS code contains Enums, like the following:
typedef NS_OPTIONS(NSUInteger, Traits) {
TraitNumberOne = 1<<0,
TraitNumberTwo = 1<<1,
);
I have never worked with Enums before in Android, and am having trouble interpreting the documentation and examples that are available. How would I translate the above example to Android code?
use this
public enum NS_OPTIONS {
TraitNumberOne (1<<0),
TraitNumberTwo (1<<1);
private final int Option;
public int getOption()
{
return Option;
}
private NS_OPTIONS(int option) {
this.Option= option;
}
}
Use it like this:
int value = NsOptions.TraitNumberOne.getOption();
Java enums are relatively simple, but can be made more complex to fit whatever needs you want to use them for. If you just want the type-safety of an enum, you can just declare the variable names like this:
public enum Traits{
TraitNumberOne,
TraitNumberTwo
}
If you want more advanced features of an enum, it's treated exactly like a class that is instantiated statically for each item in the enum. So, you can have a constructor and input whatever value you want associated with each individual item, like so:
public enum Traits{
TraitNumberOne(0x01),
TraitNumberTwo(0x02),
// future items go here
; // don't forget the semi-colon, which indicates the list of items is ending
// now, create a private variable to store the data
private final int data;
// and the constructor to set the data
private NsOptions(int data){
this.data = data;
}
// now, you can provide an accessor to provide access to the data
public int getData(){
return this.data;
}
}
You can use the above enum like this:
Traits currentOptions = Traits.TraitNumberOne;
int optionsData = currentOptions.getData();
The idea of NS_OPTIONS is to allow all possible combinations of the enumerated values to be represented by one value (this is why bitwise operators are used). In Java, I guess the equivalent would be:
public enum Permission {
TraitNumberOne (0b01),
TraitNumberTwo (0b10);
...
}
We can implement in android like ,
public enum NS_OPTIONS{
TraitNumberOne(1),TraitNumberTwo(2);
private int type;
NS_OPTIONS(int type){
this.type = type;
}
public int getType(){
return type;
}
}
and if you want to use above enum from your class you can use it like,
int i =NS_OPTIONS.TraitNumberOne;//which will return 1
int j =NS_OPTIONS.TraitNumberTwo;//which will return 2;

Using Resources in Exceptions

I have an app that uses custom Exceptions, such as this:
public class SomeException extends Exception{
private int iCode;
private String iMessage;
public SomeException(){
iCode = 201;
iMessage = **//Get the localized string R.string.error_201??**
}
#Override
public String getMessage() {
return iMessage;
}
#Override
public int getCode() {
return iCode;
}
}
Obviously, I want lo localize the error message. I have possible solutions but non of them satisfy me.
1) Pass "Context" to the constructor, and do ctx.getString(R.string.error_201)
--> Fail, as this Exceptions are sometimes thrown from MODEL classes, so they don't have a Context
2) Pass "Context" when retriveing the message in getMessage() function,
--> Fail, It's necesary to override the super method, to work as all other Exceptions.
Solution I have now: All activities in my app have this onCreate:
public void onCreate(...){
Utils.RESOURCES = getResources();
...
}
Very dirty code... I don't like the solution. My question is then,: is there a way to access the resources without the Context? And most important, How would an application such as mine solve this problem?
What about
public class MyException extends Exception {
private int iCode;
public MyException(int code) {
this.iCode = code;
}
#Override
public String getMessage() {
return "MyException code " + String.valueOf(iCode);
}
public String getLocalizedMessage(Context ctx) {
String message;
if (iCode == 201)
message = ctx.getString(R.string.error_201);
else if (iCode == 202)
message = ctx.getString(R.string.error_202);
// ...
}
}
Even if there was way to access context in different way, you should not do it. If you need to emit exceptions where you cannot pass Context, you should be able to access context before you display such error. I cannot see reason why you should create localized error messages from constructor. You can log to logcat not localized versions if you need. And where you want to display something in UI, you should have context at hand.
You can access only system wide resources without Context.
You need a Context, so I would suggest You to get it as soon as possible, and make it available through a static method or variable. You do the same thing in every Activity, but there is a cleaner method. You should make a custom Application, and override its onCreate() to make the resources public:
public class App extends Application {
private static Resources myResources;
#Override
public void onCreate() {
myResources = getBaseContext().getResources();
super.onCreate();
}
public static Resources getMyResources(){
return myResources;
}
}
The other thing you have to do is to set the Application in your manifest:
<application
android:name="{your_package}.App"
...
Now you can access the resources in all of your Activity without any preparation. Your custom Exception class could also use the externalized resources.

Android project local manually created lib

I am not sure I did the right thing. The main reason for my doubts is that I cannot find, in this or other forums, someone who has done a similar thing.
I created an abstract java class in my project. Named it lib. I put there several structures and methods used by all other classes in the project.
It works for me, but I want to know if there is a more accepted method of gathering all common methods and structures.
Note: All methods of course are declared as public static.
Note II: I did not know how to get the context within the abstract class, so if needed I had to pass it as argument to the method.
Is this wat you are looking for?
public abstract class AbstractActivity extends Activity{
public static synchronized boolean showAlertBox(Context ctx,final String title,final String message,final String okBtnTxt,final OnClickListener clickListener){
AlertDialog.Builder alertbox; alertbox = new AlertDialog.Builder(ctx);
this.runOnUiThread(new Runnable() {
#Override
public void run() {
alertbox.setTitle(title);
alertbox.setMessage(message);
if(okBtnTxt!=null || clickListener!=null)
alertbox.setNeutralButton(okBtnTxt,clickListener);
alertbox.show();
.....
}
});
return true;
}
}
In the class extending this abstract class you can just call it by using showAlertBox(this);
Other wise use AbstractActivity.showAlertBox(Context);
Well, thanks to #Matt Wolfe's comment I came to know that what I did is called "Utility class" and it is widely used to share common code in a project.
The general template is:
public abstract class lib {
public static final int ZERO = 0;
public static final int ONE = 1;
public static final int TWO = 2;
public static void func1(int i) {
}
public static void func2(int i, String s) {
}
}
and you can use it like this from any other code:
...;
lib.func1( lib.ZERO );
lib func2( lib.TWO, "sandwich" );
...;
Knowing that makes me confident that what I did is OK.
It would be perfect to find a way to avoid the prefix lib. and just have ECLIPSE, and the compiler, find the right import and recognize the function with just its name, like they do for global libraries.

Categories

Resources