Android DOM object to string - android

I am basically stuck with my DOM object with the data I want and I'm trying to output that to a string. Here here the code I am using to parse my xml file:
public ORGRTools insertUserNameAndPassword(String userName, String password)
{
try {
DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
docBuilder = factory.newDocumentBuilder();
dom = docBuilder.parse (new File("/mnt/sdcard/Commands.xml"));
NodeList items = dom.getElementsByTagName("login");
for (int i = 0; i < items.getLength(); i++) {
Node item = items.item(i);
NodeList properties = item.getChildNodes();
for (int j = 0; j < properties.getLength(); j++) {
Node property = properties.item(j);
String name = property.getNodeName();
if (name.equalsIgnoreCase("userName")) {
property.getFirstChild().setNodeValue(userName);
}
if (name.equalsIgnoreCase("password")) {
property.getFirstChild().setNodeValue(password);
}
}
}
} catch (SAXException e) {
// TODO Auto-generated catch block
//invalid character in xml
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return this;
}
That being said, I have the following function that uses the member variable dom from the previous code above to try to get its string representation:
public String serialize()
{
try
{
DOMSource domSource = new DOMSource(dom);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
String retVal= writer.toString();
return retVal;
}
catch(TransformerException ex)
{
//exception here but does not print stack trace... weird
ex.printStackTrace();
return null;
}
}
However, I get the following exception(see comment). Does anyone have a clue what's going on? Whys is transformation to string failing? I've been stuck in this for a few hours so any help would be good. Any API level is ok.
Thanks!
--Edit--
Here is the structure I am trying to process. Basically, the idea is to have one of these models installed with the .apk and have these models communicate with a server. So I need to fill in the user credential data:
<commands>
<login>
<userName>itemstr</userName>
<password>itemstr</password>
</login>
<analyse>
<imageName>itemstr</imageName>
<imageHeight>itemnum</imageHeight>
<imageWidth>itemnum</imageWidth>
<recordID>itemstr</recordID>
</analyse>
<retrieve>
<record>itemnum</record>
</retrieve>

Refer to simple xml framework it will be more easy to work with serializing xml to object.
Here is sample to explain u about its use...
Serializing a simple object
In order to serialize an object to XML a series of annotations must be placed within that object. These annotations tell the persister how the object should be serialized. For example take the class shown below. Here there are three different annotations, one used to describe the name of the root element, one that describes an XML message element, and a final annotation for an id attribute.
#Root
public class Example {
#Element
private String text;
#Attribute
private int index;
public Example() {
super();
}
public Example(String text, int index) {
this.text = text;
this.index = index;
}
public String getMessage() {
return text;
}
public int getId() {
return index;
}
}
To serialize an instance of the above object a Persister is required. The persister object is then given an instance of the annotated object and an output result, which is a file in this example. Other output formats are possible with the persister object.
Serializer serializer = new Persister();
Example example = new Example("Example message", 123);
File result = new File("example.xml");
serializer.write(example, result);
Hope this answers ur question..

Related

How to switch between AndroidElement and WebElement?

I m working on Mobile Web Application Automation. Here I m using Java, Selenium and Appium. There are two fields which I m not able to automate. They are Date and drop down fields. I can able automate text fields, check boxes and radio buttons. When clicking on Date Field, there comes the Android default date picker, in which I cant able to pick a date. Here is my code below:
class openBrowser() {
public static WebDriver driver;
public static AppiumDriver<MobileElement> androidDriver;
#Test
public static void launchBrowser(){
desiredCapabalities(...);
androidDriver = new AndroidDriver<MobileElement>(new
URL("http://localhost:4723/wd/hub", desiredCapabilities));
driver = androidDriver;
}
class pickDate() {
MobileElement element;
try{
element = (MobileElement)
androidDriver.findElementByXPath("//android.view.View[#content-desc='28 May
2017']").click();
}catch(Exception e) {
throw e;
}
}
"findElementByXPath()" looks only for the web element, but not searching for Android/Mobile element. Please refer date picker screenshot: Date picker
Kindly suggest me any solution to switch between Web Element and Android/Mobile Element. Thanks in advance.
I found a solution from the below link:
switch contexts i.e Native App and Web View
public static void switchToContext(String context) throws Exception {
try {
RemoteExecuteMethod executeMethod = new RemoteExecuteMethod((RemoteWebDriver) androidDriver);
Map<String,String> params = new HashMap<>();
params.put("name", context);
executeMethod.execute(DriverCommand.SWITCH_TO_CONTEXT, params);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String getCurrentContextHandle() throws Exception{
try{
RemoteExecuteMethod executeMethod = new RemoteExecuteMethod((RemoteWebDriver) androidDriver);
String context = (String) executeMethod.execute(DriverCommand.GET_CURRENT_CONTEXT_HANDLE, null);
return context;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
public static List<String> getContextHandles() throws Exception{
try {
RemoteExecuteMethod executeMethod = new RemoteExecuteMethod((RemoteWebDriver) androidDriver);
List<String> contexts = (List<String>) executeMethod.execute(DriverCommand.GET_CONTEXT_HANDLES, null);
return contexts;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

Android XML Multi-Node Reading Using Current Date

I'm creating a weather app which gets the min/max temperature from a 5 day forecast XML with same node names. I want to use the current date to look through the XML and find the correct min/max for that day.
This is the weather XML: Link
Here is my code, I've trimmed it just enough to the part where I don't understand the multi-nodes, but still I wanted it to be reusable (Currently it just gets the first min/max as denoted by a 0):
public class MyAsyncTask extends AsyncTask < Void, Void, String > {
//========================== pre execute to get date for xml =======
protected void onPreExecute() {
try {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
} catch (Exception e) {}
}#
Override
protected String doInBackground(Void...params) {
//=========================== Load data using xml ================
try {
URL xmlUrl2 = new URL("http://api.openweathermap.org/data/2.5/forecast/daily?q=london&mode=xml&units=metric&cnt=5");
InputStream inm = xmlUrl2.openStream();
Document docm = parsem(inm);
docm.getDocumentElement().normalize();
Node nNodem = docm.getElementsByTagName("temperature").item(0);
Element eElementm = (Element) nNodem;
double dmax = Math.round(Double.parseDouble(eElementm.getAttribute("max")));
int dxmax = (int) dmax;
xmaxtemp = Integer.toString(dxmax);
double dmin = Math.round(Double.parseDouble(eElementm.getAttribute("min")));
int dxmin = (int) dmin;
xmintemp = Integer.toString(dxmin);
} catch (UnknownHostException s) {
internet = false;
} catch (IOException i) {
System.out.println("IO Exception error!");
} catch (Exception ex) {
ex.printStackTrace();
}
return xtemp;
}
//========================= show data===============
#
Override
protected void onPostExecute(String result) {
TextView minmax = (TextView) findViewById(R.id.minmax);
minmax.setText("↑" + xmaxtemp + " " + xmintemp + "↓");
}
//======================== parse document =======
public static Document parse(InputStream is) {
Document ret = null;
DocumentBuilderFactory domFactory;
DocumentBuilder builder;
try {
domFactory = DocumentBuilderFactory.newInstance();
domFactory.setValidating(false);
domFactory.setNamespaceAware(false);
builder = domFactory.newDocumentBuilder();
ret = builder.parse(is);
} catch (Exception ex) {
System.err.println("unable to load XML: " + ex);
}
return ret;
}
}
For better use, u should use xpath to have a perfect manipulation over ur xml data:
this is an example how to get all temperature nodes
String expression = "//temperature";
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
After that you can manipulate the list.
this is a good tuto to start using xpath with java:
java-xml-xpath-tutorial/

Android - getString method error

I've got a slight problem with a getString function in my Android code.
I create a string and I want to use it to retrieve a String which is part of a JSON Array but I get the following error:
The method getString(String) is undefined for the type String
This is the specific code for this section:
private void read_JSON()
{
JSONArray jsa2 = new JSONArray();
for (int i=0; i < jsa2.length(); i++)
{
try
{
JSONObject jso2 = new JSONObject();
jso2 = jsa2.getJSONObject(i);
String one = one.getString("Blur");
//esbrinar com arreglar aixo!!
}catch (JSONException e)
{
e.printStackTrace();
}
}
}
"Blur" is a String which is part of a JSONArray, defined here:
private void create_JSON()
{
JSONObject jso = new JSONObject();
try {
jso.put("Nombre","Miguel");
jso.put("Apellidos", "Garcia");
jso.put("Año_nacimiento", 1990);
JSONArray jsa = new JSONArray();
jsa.put("Blur");
jsa.put("Clur");
jso.put("Nombres_Hijos", jsa);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Could you help me understand what I'm doing wrong?
Thank you very much.
Yours sincerely,
Mauro.
jso2.getString("Blur") might be what you're trying to call. I believe you want to extract a string from the JSONObject you just got from JSONArray. What you actually wrote is to extract string from the string you just defined.

Parsing JSON in Android Master/Detail Flow

As the title says. I'd like to just use a JSON. Here is my code for what I'm guessing is my main activity. This grabs all the contents and places them in their respectful variables I'm hoping. Placed at the beginning:
public class WordDetailActivity extends FragmentActivity {
// Reading text file from assets folder
StringBuffer sb = new StringBuffer();
BufferedReader br = null; {
try {
br = new BufferedReader(new InputStreamReader(getAssets().open(
"wordlist.txt")));
String temp;
while ((temp = br.readLine()) != null)
sb.append(temp);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close(); // stop reading
} catch (IOException e) {
e.printStackTrace();
}
}
String myjsonstring = sb.toString();
// Try to parse JSON
try {
// Creating JSONObject from String
JSONObject jsonObjMain = new JSONObject(myjsonstring);
// Creating JSONArray from JSONObject
JSONArray jsonArray = jsonObjMain.getJSONArray("employee");
// JSONArray has four JSONObject
for (int i = 0; i < jsonArray.length(); i++) {
// Creating JSONObject from JSONArray
JSONObject jsonObj = jsonArray.getJSONObject(i);
// Getting data from individual JSONObject
int id = jsonObj.getInt("id");
String word = jsonObj.getString("word");
String dictionary = jsonObj.getString("dictionary");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
Now I have another file called WordContent.java that defines these variable again (a non edited version):
public static Map<String, WordItem> ITEM_MAP = new HashMap<String, WordItem>();
static {
// Add 3 sample items.
addItem(new WordItem("1", "This Word", "Blah blah blah"));
}
private static void addItem(WordItem item) {
ITEMS.add(item);
ITEM_MAP.put(item.id, item);
}
/**
* A dummy item representing a piece of content.
*/
public static class WordItem {
public String id;
public String word;
public String dictionary;
public WordItem(String id, String word, String dictionary) {
this.id = id;
this.word = word;
this.dictionary = dictionary;
}
#Override
public String toString() {
return word;
}
}
}
I haven't edited them yet because I have no idea where to go from here. Or rather how to put the contents of my JSON to the WordItem so they show up when I run the program. Another way to look at all of my code that is similar to this is to just create a Master/Detail Flow project in the Eclipse ADT bundle. I hope I'm saying all of this right. Let me know if there are more details I should shed. Very new to Android Dev but any pointer in the right direction is greatly appreciated.
Personally, I would do the JSON parsing in a separate file and probably use an AsyncTask. This is so you can decouple your files/classes as you really do not need an Activity for the parsing.
I tried to reuse as much of your code you posted above. With that being said, something like this should work or put you in the right direction:
public class ParseJsonTask extends AsyncTask<Void, Void, String> {
private Context mCtx;
public ParseJsonTask(Context ctx) {
this.mCtx = ctx;
}
#Override
protected String doInBackground(Void... params) {
// Reading text file from assets folder
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(mCtx.getAssets().open("wordlist.txt")));
String temp;
while ( (temp = br.readLine()) != null )
sb.append(temp);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close(); // stop reading
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.tostring();
}
#Override
protected void onPostExecute(Void jsonString) {
WordContent word = new WordContent(); // We use this oject to add the JSON data to WordItem
// Try to parse JSON
try {
// Creating JSONObject from String
JSONObject jsonObjMain = new JSONObject(jsonString);
// Creating JSONArray from JSONObject
JSONArray jsonArray = jsonObjMain.getJSONArray("employee");
// JSONArray has four JSONObject
for (int i = 0; i < jsonArray.length(); i++) {
// Creating JSONObject from JSONArray
JSONObject jsonObj = jsonArray.getJSONObject(i);
// Getting data from individual JSONObject
int id = jsonObj.getInt("id");
String word = jsonObj.getString("word");
String dictionary = jsonObj.getString("dictionary");
// We can use the three variables above...
word.addItem(new WordItem(id, word, dictionary));
// or we can simply do...
// word.addItem(new WordItem(jsonObj.getInt("id"), jsonObj.getString("word"), jsonObj.getString("dictionary")));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Now whenever you want to parse the JSON file and use the class above you simply do the following:
ParseJsonTask task = new ParseJsonTask(getBaseContext());
task.execute();
Let me know if you have any questions...

Handle errors for rss parser

I have a rss feed reader application. The goal is to store the title and image for each item in a custom object named RSSItem, and oll the RSSItem objects in another object named RSSFeed. The problem is that if an item element does not have an enclosure element SaxException is thrown. How should I handle the errors with this parser? Here is the parser code:
public class Parser {
private final String RSS_ELEMENT = "rss";
private final String CHANNEL_ELEMENT = "channel";
private final String ITEM_ELEMENT = "item";
private final String ENCLOSURE_ELEMENT = "enclosure";
private final String TITLE_ELEMENT = "title";
private final String URL_ATTRIBUTE = "url";
private final String TYPE_ATTRIBUTE = "type";
private final String IMAGE_TYPE = "image/jpeg";
RSSItem rssItem;
RSSFeed rssFeed;
final URL mFeedUrl;
public Parser(String feedUrl) {
try {
mFeedUrl = new URL(feedUrl);
} catch (MalformedURLException e) {
Log.e(e.getClass().getSimpleName(), e.getMessage());
throw new RuntimeException(e);
}
rssFeed = new RSSFeed();
}
protected InputStream getInputStream() {
try {
return mFeedUrl.openConnection().getInputStream();
} catch (IOException e) {
Log.e(e.getClass().getSimpleName(), e.getMessage());
return null;
}
}
public RSSFeed parse() {
InputStream istream = getInputStream();
RootElement root = new RootElement(RSS_ELEMENT);
Element channel = root.requireChild(CHANNEL_ELEMENT);
Element itemElement = channel.requireChild(ITEM_ELEMENT);
Element enclosure = itemElement.requireChild(ENCLOSURE_ELEMENT);
Element title = itemElement.requireChild(TITLE_ELEMENT);
enclosure.setStartElementListener(new StartElementListener() {
public void start(Attributes attrs) {
String imageType = attrs.getValue(TYPE_ATTRIBUTE);
if (imageType.equals(IMAGE_TYPE)) {
try {
String imageUrl = attrs.getValue(URL_ATTRIBUTE);
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
rssItem.setImage(bitmap);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
title.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
rssItem.setTitle(body);
}
});
itemElement.setStartElementListener(new StartElementListener() {
public void start(Attributes arg0) {
rssItem = new RSSItem();
}
});
itemElement.setEndElementListener(new EndElementListener() {
public void end() {
rssFeed.addItem(rssItem);
}
});
try {
Xml.parse(istream, Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
e.printStackTrace();
}
return rssFeed;
}
}
I would not recommend trying to implement your own RSS parser , but rather using a standard library for that.
It's fairly easy to setup an implementation of a SAX parser but the hard part is to be able to parse any and every feed under the sun.
You need to cater to all formats RSS 1, RSS 2, Atom etc. Even then you will have to contend with poorly formatted feeds.
I had faced similar problems in the past so decided to do my feed parsing on a server and just get the parsed contents. This allows me to run more complex libraries and parser which I can modify without pushing out updates for my app.
I have the following service running on AppEngine which allows for a much simpler XML / JSON parsing at your end. There is a fixed and simple structure to the response. You can use this for parsing
http://evecal.appspot.com/feedParser
You can send both POST and GET requests with the following parameters.
feedLink : The URL of the RSS feed response : JSON or XML as the response format
Examples:
For a POST request
curl --data-urlencode "feedLink=http://feeds.bbci.co.uk/news/world/rss.xml" --data-urlencode "response=json" http://evecal.appspot.com/feedParser
For GET request
evecal.appspot.com/feedParser?feedLink=http://feeds.nytimes.com/nyt/rss/HomePage&response=xml
My android app "NewsSpeak" uses this too.

Categories

Resources