Issue in looping to parse - java

I have an xml with 'n' number of data which i am parsing,for test i hardcoded without looping has below,now the below line is just parsing and showing the data for index '1' ,i need to loop this and i am not sure how can i do this.How do i find the length of obj and loop,i cannot find any method in SoapObject.I used like below but the data is getting overridden after parsing
GetReminder getReminder=new GetReminder();
SoapObject obj=(SoapObject)envelope.getResponse();
for(int i=0;i<obj.getPropertyCount();i++) {
KSoap2ResultParser.parseBusinessObject(obj.getProperty(i).toString(), getReminder);}
and the parser is
public static void parseBusinessObject(String input, Object output) throws NumberFormatException, IllegalArgumentException, IllegalAccessException, InstantiationException{
System.out.println("input----> " +input);
Class theClass = output.getClass();
Field[] fields = theClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Type type=fields[i].getType();
System.out.println("type--" +type);
fields[i].setAccessible(true);
//detect String
if (fields[i].getType().equals(String.class)) {
String tag = fields[i].getName() + "="; //"s" is for String in the above soap response example + field name for example Name = "sName"
System.out.println("fff------------"+tag);
if(input.contains(tag)){
String strValue = input.substring(input.indexOf(tag)+tag.length(), input.indexOf(";", input.indexOf(tag)));
System.out.println("strvalue------------"+strValue);
if(strValue.length()!=0){
fields[i].set(output, strValue);
}
}
}
//detect int or Integer
if (type.equals(Integer.TYPE) || type.equals(Integer.class)) {
String tag = fields[i].getName() + "="; //"i" is for Integer or int in the above soap response example+ field name for example Goals = "iGoals"
if(input.contains(tag)){
String strValue = input.substring(input.indexOf(tag)+tag.length(), input.indexOf(";", input.indexOf(tag)));
System.out.println("strvalue------------"+strValue);
if(strValue.length()!=0){
fields[i].setInt(output, Integer.valueOf(strValue));
}
}
}
//detect float or Float
if (type.equals(Float.TYPE) || type.equals(Float.class)) {
String tag = "f" + fields[i].getName() + "=";
if(input.contains(tag)){
String strValue = input.substring(input.indexOf(tag)+tag.length(), input.indexOf(";", input.indexOf(tag)));
if(strValue.length()!=0){
fields[i].setFloat(output, Float.valueOf(strValue));
}
}
}
}

You just have to do a for loop on the property count available in the SaopObject.
SoapObject obj=(SoapObject)envelope.getResponse();
int nbProperties = obj.getPropertyCount();
for (int i = 0; i < nbProperties; i++) {
KSoap2ResultParser.parseBusinessObject(obj.getProperty(i).toString(), getReminder);
// Do something with getReminder object
}
Note: if the ouput Object is added to a list for instance, then you should allocate a new ouput object in order for each call to parseBusinessObject() to set the field in a fresh object. E.g.
// Create the list that shall contains the read properties
List<GetReminder> reminders = new ArrayList<>();
SoapObject obj=(SoapObject)envelope.getResponse();
Log.d("Result --ddd- ", obj.toString() );
System.out.println("obj---->" + obj.getPropertyCount());
for(int i=0; i < obj.getPropertyCount(); i++) {
System.out.println("here i is.........." +i);
// Create a new instance
GetReminder rem = new GetReminder();
// Read and set the fields values of rem
KSoap2ResultParser.parseBusinessObject(obj.getProperty(i).toString(), rem);
// Don't forget to store the new reminder in the list
reminders.add(rem);
}
// Do what you want with the list of reminders

Related

How to unstructure a text string that has characters and convert it to an object

I have a text string that I receive from PL/SQL. I need to convert each object that is separated by a ';'.
This is my string enter image description here
I need to get that information and create the objects that come in that string.
//all objects come in a single text string
first object is 830114921-1<,>TIGO<,>13<,>RECARGA CELULAR TIGO;
second object is 800153993-7<,>PROTOCOLO CLARO<,>426<,>PAQUECLARO 24HRS;
third object is 800153993-7<,>PROTOCOLO CLARO<,>7<,>PINES 2000;
fourth object is 900102005-1<,>GLOBAL TV TELECOMUNICACIONES<,>92<,>JOHATRUJILLO;
Example:
Class MyClass{
Integer number;
String text;
Integer number2;
String text;
}
List<MyClass> myList = new ArrayList<>();
myClass.SetNumber(830114921-1);
myClass.SetText("TIGO");
myClass.SetNumber2(13);
myClass.SetText2("RECARGA CELULAR TIGO");
myList.add(myClass);
//I can split the 4 objects but if more objects come in the text string, can //no longer be.
String str = "830114921-1<,>TIGO<,>13<,>RECARGA CELULAR TIGO;"
+ " 800153993-7<,>PROTOCOLO CLARO<,>426<,>PAQUECLARO 24HRS; "
+ "800153993-7<,>PROTOCOLO CLARO<,>7<,>PINES 2000; "
+ "900102005-1<,>GLOBAL TV TELECOMUNICACIONES<,>92<,>JOHATRUJILLO;";
String[] arrOfStr = str.split(";", 4);
List<String> list = new ArrayList<>();
for (String a : arrOfStr) {
list.add(a);
}
for (String data : list) {
String result2 = data.replaceAll("\\<,>", " ");
System.out.println(result2);
}
You can count how many ; exits in the String and then use str.split()
...
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ';') {
count++;
}
}
String[] arrOfStr = str.split(";", count);// instead of 4
...
This will solve you problem but there are better ways to do it, using a regular expression . Learn more here
Edit :
You also need to do the same thing to every attribute of your object but the counting is a little bit different :
...
count = 0;
for (int i = 1; i < arrOfStr[0].length()-1; i++) {
if (arrOfStr.charAt(i-1) == '<'arrOfStr.charAt(i) == ',' && arrOfStr.charAt(i+1) == '>') {
count++;
}
}
List<String> listOfObjectsFromSQL = new ArrayList<MyClass>();
String[] attributes = new String[count];
for (String strObj : arrOfStr) {
attributes = strObj.split("<,>", count);
//create you object
MyClass obj = new MyClass();
//fill your object with values from the query
obj.setNumber(attributes[0]);
obj.setText(attributes[1]);
obj.setNumber2(attributes[2]);
obj.setText2(attributes[3]);
//add them to your list to use them...
listOfObjectsFromSQL.add(obj);
}
...
The data is split with <,> and ; so you should easily be able to split the string and collect the data. Java has a String.split() method. First split the string object that contains all the data into an array of strings by splitting on ; and then loop over these and split them on <,>.
At this point you should be able to set your attributes according to the order of the data in the string (assuming these are ordered properly).

How do I print a 2d array?

My array is:
String[][] name = new String[15][2];
int rowNumber = 0;
My add button is:
name[rowNumber][0] = firstName.getText();
name[rowNumber][1] = lastName.getText();
I do not know what to put in my list button (lists the first name and last name) into my TextArea called outPut.
The Whole Code:
`
public class StudentGradesView extends FrameView {
String[][] name = new String[15][2];
double[][] testMark = new double[15][4];
int rowNumber = 0;
private void btnAddMouseClicked(java.awt.event.MouseEvent evt) {
name[rowNumber][0] = firstName.getText();
name[rowNumber][1] = lastName.getText();
rowNumber ++;
}
private void btnListMouseClicked(java.awt.event.MouseEvent evt) {
String outputStr = "";
for(int i=0; i < rowNumber; i++) {
outputStr += name[rowNumber][0] + " " + name[rowNumber][1] + "\n";
}outPut.setText(outputStr);
}
}`
Okay, I think I get what you want now.
First we take the inputs...
name[numberOfInputs][0] = firstName.getText();
name[numberOfInputs][1] = lastName.getText();
numberOfInputs += 1;
Now you want to output this to a textarea...
String outputStr = "";
for(int i=0; i < numberOfInputs; i++) {
outputStr += name[i][0] + " " + name[i][1] + "\n";
}
Then set your output textarea
outPut.setText(outputStr);
You are getting nulls because you are specifying a static array size but you (probably) are not filling up the array with test cases up to that amount. So you are printing elements of the array that are simply not populated.
Edit: for comments.
String st = "";
for (int i = 0; i < 15; i++)
st += name[i][0] + " " + name[i][1] + "\n";
outPut.setText(value);
This loops over the array and creates a string containing all the full names, separated by a line break.
This then sets the text using outPut.setText(value);
for(String[] s1d : s2d)
for(String s : s1d)
System.out.println(s);
A simple way using for() construct
The easiest way to print any array to any depth is to use Arrays.deepToString():
System.out.println(Arrays.deepToString(array));
try this:
import java.util.Arrays;
.
.
.
String[][] a = { { "john" },
{ "jones" }
};
System.out.println(Arrays.deepToString(a)); //whole string array
System.out.println(Arrays.deepToString(a[0])); //john
System.out.println(Arrays.deepToString(a[1])); //jones

how to place the values in get from my loop into an arraylist?

I have this code
for (int i = 0; i < friendslocations.length(); i++)
{
JSONObject c = friendslocations.getJSONObject(i);
String friendName = c.getString(TAG_FRIENDNAME);
System.out.println("friend name " + friendName);
String friendLocation = c.getString(TAG_LOCATION);
System.out.println("friendlocation" + friendLocation);
}
where it keeps printing me the values i want.
But I need to know how to place the values that come out from this loop (the friendname and the friendloaction ) in an array list where each index contains this (friendname, friendlocation).
So how can i do this?
Wrap your two attributes in a new Object and push that object into the arraylist.
class FriendData {
public String friendName;
public String friendLocation
public FriendData(String friendName, String friendLocation) {
this.friendName=friendName;
this.friendLocation=friendLocation;
}
public String toString() {
return "friendName="+friendName+" friendLocation="+friendLocation;
}
}
List<FriendData> friendsList = new ArrayList<>();
for (int i = 0; i < friendslocations.length(); i++) {
JSONObject c = friendslocations.getJSONObject(i);
String friendName = c.getString(TAG_FRIENDNAME);
String friendLocation = c.getString(TAG_LOCATION);
friendsList.add(new FriendData(friendName, friendLocation));
}

Create a new array index if it doesn't exist

Say I have a String like below
String s1 = "test1=1&test2=2&test3=&test4=4";
Pls note the test3 parameter in the string S1 as it doesn't have any value
String [] splitS1 = s1.split("\\&");
for (int i = 0; i < splitS1.length; i++) {
String[] params = splitS1[i].split("=");
System.out.println("Attribute:"+params[0]+" Value : "+params [1]);
}
Above code throws java.lang.ArrayIndexOutOfBoundsException: 1 because test3 in String s1 doesn't have any value so params[1] is not valid with respect to test3.
I tried doing this
if(params.length == 1) {
params[1] = "";
}
But I know that we can't extend the array. What can be done here?
Thanks!
The split method that takes one parameter discards trailing empty tokens. Here, this results in params having only a length of one.
User the split method that also takes a limit parameter, and pass a negative limit to ensure that you get an array with a length that matches the number of tokens actually present: 2.
String[] params = splitS1[i].split("=", -1);
Then you won't have to create another array; you'll get an array of size 2 to start with, assuming there is an = present.
The easiest thing would be to test the array length:
String splitS1 = s1.split("\\&");
for (int i = 0; i < splitS1.length; i++) {
String[] params = splitS1[i].split("=");
System.out.println(
"Attribute: " + params[0] +
" Value : " + (params.length < 1 ? "<no value>" : params[1]));
}
It might also be worth using printf instead of println:
System.out.printf("Attribute: %1$s%n Value : %2$s%n",
params[0],
params.length < 1 ? "<no value>" : params[1]
);
Create a class representing a parameter, with its name and value and which parses the string:
public final class Parameter {
private final String name;
private final String value;
public Parameter(String name, String value) {
this.name = name;
this.value = value;
}
public static Parameter parse(String s) {
String[] parts = s.split("=");
String name = parts[0];
String value = "";
if (parts.length > 1) {
value = parts[1];
}
return new Parameter(name, value);
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
// add more behavior if needed.
}
And now you can do
for (int i = 0; i < splitS1.length; i++) {
Parameter param = Parameter.parse(splitS1[i]);
System.out.println("Parameter:" + param.getName() + " = " + param.getValue());
}
Create a new String array and copy the result of split into it.
String[] cpy = new String[2];
for(int i=0;i<cpy.length;i++){
cpy[i] = params[i];
}
params = cpy;
You can do some thing like this
String s1 = "test1=1&test2=2&test3=&test4=4";
String[] splitS1 = s1.split("\\&");
for (int i = 0; i < splitS1.length; i++) {
String[] params = splitS1[i].split("=");
String[] para=new String[2];
if(params.length==1) {
para[0]=params[0];
System.out.println("Attribute:"+para[0]+" Value : "+para [1]);
}
else{
System.out.println("Attribute:"+params[0]+" Value : "+params [1]);
}
}
or
if(params.length==1) {
System.out.println("Attribute:"+para[0]+" Value : "+"");
}
else{
System.out.println("Attribute:"+params[0]+" Value : "+params [1]);
}

Algorithm to search and replace delimited parameters

I have a string that contains multiple parameters delimited by #, like this :
.... #param1# ... #param2# ... #paramN# ...
And I want to replace the parameter placeholders by values.
The current algorithm looks like this:
//retrieve place holder into this SQL select
Pattern p = Pattern.compile(DIMConstants.FILE_LINE_ESCAPE_INDICATOR);
Matcher m = p.matcher(sqlToExec); // get a matcher object
int count = 0;
int start = 0;
int end = 0;
StringBuilder params = new StringBuilder();
while (m.find()) {
count++;
if (count % 2 == 0) {
// Second parameter delimiter
String patternId = sqlToExec.substring(start, m.end());
//Clean value (#value#->value)
String columnName = patternId.substring(1, patternId.length() - 1);
//Look for this column into preLoad row ResultSet and retrieve its value
String preLoadTableValue = DIMFormatUtil.convertToString(sourceRow.get(columnName));
if (!StringUtils.isEmpty(preLoadTableValue)) {
aSQL.append(loadGemaDao.escapeChars(preLoadTableValue).trim());
} else {
aSQL.append(DIMConstants.COL_VALUE_NULL);
}
params.append(" " + columnName + "=" + preLoadTableValue + " ");
end = m.end();
} else {
// First parameter delimiter
start = m.start();
aSQL.append(sqlToExec.substring(end, m.start()));
}
}
if (end < sqlToExec.length()) {
aSQL.append(sqlToExec.substring(end, sqlToExec.length()));
}
I'm looking for a simplest solution, using regexp or another public API. Input parameters will be the source string, a delimiter and a map of values. Output parameter will be the source string with all the parameters replaced.
If this is for a normal SQL query, you might want to look into using PreparedStatements
Beyond that, am I missing something? Why not just use String.replace()? Your code could look like this:
for(int i = 0; i < n; i++){
String paramName = "#param" + i + "#"
sqlToExec = sqlToExec.replace(paramName,values.get(paramName));
}
That assumes you have a map called "values" with string mappings between parameters in the form "#paramN#"
If you need it more generic, this will find and return the whole param including the #'s:
public class ParamFinder {
public static void main(String[] args) {
String foo = "#Field1# #Field2# #Field3#";
Pattern p = Pattern.compile("#.+?#");
Matcher m = p.matcher(foo);
List matchesFound = new ArrayList();
int ndx = 0;
while(m.find(ndx)){
matchesFound.add(m.group());
ndx = m.end();
}
for(Object o : matchesFound){
System.out.println(o);
}
}
}

Categories