Android search XML based on some condition - android

Here is what I am trying : I have a list of names. I want to search an XML file depending on that names.
XML looks like this :
<book>
<string> book name </string>
<array>
<string> Name1 </string>
<string> Name2 </string>
</array>
</book>
Now I want to search say "Name1" and if it matches I want to get the name of the book.
Is this possible? If yes can someone provide some code/snippet or maybe tell me the steps how I can do it. Thank you

Android has some built-in XML parsing functions. Take a look at http://developer.android.com/training/basics/network-ops/xml.html
Basically:
1) Set up an InputStream for the XML content (if you are downloading it, or reading it from a getResources() for example)
2) Set up your parser: XmlPullParser parser = Xml.newPullParser();
3) Start reading the XML in a loop. When parser.getName().equals("book"), then continue on until you get to your parser.getName().equals("string") and save the results of parser.getText(); Then when you continue on and hit parser.getName().equals("array") and you continue on again to parser.getName().equals("string"), then check the results of parser.getText() to see if it matches your search string.
Clear as mud?
Parsing XML is a lot harder than it was advertised to be 20 years ago or so, but once you understand that the parser reads the XML as it comes in, it makes it a little easier to see the overall picture of how to implement it. Study up on that link, it gives you everything you need to know.

There is a lot of ways to parse XML, I suggest you to use Jsoup
Its really easy to extract data from XML.
String html = "<?xml version=\"1.0\" encoding=\"UTF-8\">
<book>
<string> book name </string>
<array>
<string> Name1 </string>
<string> Name2 </string>
</array>
</book></xml>";
Document doc = Jsoup.parse(html, "", Parser.xmlParser());
Element book = doc.select("book").first();
Element bookName = book.getElementsByTag("string").first();
Elements array = book.getElementsByTag("array");
for (Element e : array.select("string")) {
//....
}

Thank you all for the answers. I am using the using the tutorial here and wrote this method to search the XML.
public List<String> search(String key, String url){
List<String> items = new ArrayList<String>();
XmlParser parser = new XmlParser();
String xml = parser.getXmlFromUrl(url); // getting XML
Document doc = parser.getDomElement(xml);
NodeList nl = doc.getElementsByTagName("book");
for(int i = 0; i<nl.getLength();i++){
Element e = (Element) nl.item(i);
NodeList n = e.getElementsByTagName("string");
if(parser.getElementValue(n.item(1)).equals(key) ||
parser.getElementValue(n.item(2)).equals(key) ){
items.add(parser.getElementValue(n.item(0)));
}
}
return items;
}

Related

Android XML parsing issues using SAX parser

I am parsing an XML file from assets folder to dump my data into the database. Later on i may fetch this and display it in a text view. But while parsing i am losing some data, ie, if i have some 50 words within the XML tags before parsing, in my database i am not able to find all of them after parsing.
For exmple:
I am parsing this line:
<about>Skandagiri also known as kalavara durga, is an ancient mountain fortess located approximately 70km from Banglore city and 3 km from Chikkaballapur in the Indian State of Karnataka.It is off Bellary road(NH 7, Hyderabad to Bangalore Highway) and overlooks Nandi Hills, Mudddenahalli and Kanive narayanapura.The peak is at an altitude of about 1350 meters</about>
after parsing in my database:
at an altitude of about 1350
i am using String to hold my parsed value like this:
if (element.equalsIgnoreCase("about")){
String str=parsedValue;
}
If you are using SAXparser than it is better to wrap the data with StringBuffer.
Take a look in oficial documentation : ContentHandler.
Here is the interesting part from it :
The Parser will call this method to report each chunk of character data. SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks; however, all of the characters in any single event must come from the same external entity so that the Locator provides useful information.
Plaese try Below code..I think solved your issue.
Element element = (Element) node.item(i);
NodeList id = element.getElementsByTagName("about");
Element line1 = (Element) id.item(0);
if (null != line1)
AdsFound[i] = getCharacterDataFromElement(line1);
else
AdsFound[i] = "";
Use a StringBuffer, since text can be read in chunks and you may be reading just the part of code.
use string buffer and append all the chunks, so that finally you will get the complete text without missing out any data.
Like this:
StringBuffer strbufr = new StringBuffer();
if (element.equalsIgnoreCase("about")){
String str = strbufr.toString().trim();
}
#Override
public void characters(char[] ac, int i, int j) throws SAXException {
strbufr.append(ac, i, j);
}

Get Attribute values and map this values together using SAX parser

here i want to get parse Map values in one array list or hash-map i dnt know which is the better way.
Here is my XMl file
I am using SAX parser to parse this thing
<Navigation useNavi="1" auto="1" diable="0" >
<Map MapName="paris" MapPath="\Storage Card\PA\xyz" LoadAtStartup="1" />
<Map MapName="swiss" MapPath="\Storage Card\SW\abc" LoadAtStartup="0" />
<Map MapName="delhi" MapPath="\Storage Card\DE\del" LoadAtStartup="1" />
</Navigation>
Here i want to pasre Map tag , i cant do it easily and also get its attributes values but i want to know how can i manage this Map element attributes values for a example MapName is paris and i want to use its respective values in future like LoadAtStartup attribute value.
How can i manage these 3 maps values ?
Thanks
Sam
Create a class:
class MapObject
public string MapName;
public string MapPath;
public boolean LoadAtStartup;
public MapObject(string name, string path, boolean loadAtStartup){
this.MapName = name;
this.MapPath = path;
this.LoadAtStartup = loadAtStartup;
}
And a container for the class instances:
List<MapObject> mapsObjects = new List<MapObject>();
And new instances in your JSON parser (pseudo code, you already have this)
for each object in JSON data{
mapObjects.add(new MapObject(name attribute, path attribute, loadAtStartup attribute);
}
There are different solutions for your question. Maybe the following will give you a possible solution:
HashMap<String, Pair<String, Boolean>> mapEntries = new HashMap<String, Pair<String,Boolean>>();
//Inside SAX callback
String place = attrs.getValue("MapName");
String path = attrs.getValue("MapPath");
Boolean isLoadAtStartup = Integer.parseInt(attrs.getValue("LoadAtStartup")) == 1;
mapEntries.put(place, new Pair<String, Boolean>(path, isLoadAtStartup));
The above uses the android.util.Pair class. You can use your user-defined container class (as illustrated by #Simon) as well.

How to retrieve xml elements in android using DOM

I have created an xml file and stored in my sdcard.I am using DOM parser to retrieve it.My xml file is like.I have used a simple xml file for demo.It is:
<?xml version="1.0"?>
<root>
<staff>
<word>1</word>
<meaning>one</meaning>
</staff>
<staff>
<word>2</word>
<meaning>two</meaning>
</staff>
</root>
In my activity i have an autocompletetextview.In it when i enter 1 which is given in word it should show the value "one" which is given in its meaning.Is it possible to do this and how?
Get node list by using getElementsByTagName("staff")
get child nodes getChildNodes()
Now get nodename getNodeName() and node value getNodeValue()
See this below code:
Element root=doc.getDocumentElement();
NodeList nodeList=root.getElementsByTagName("staff");
for(int i=0;i<nodeList.getLength();i++)
{
Node statenode=nodeList.item(i);
NodeList idList= statenode.getChildNodes();
for(int j=0;j<idList.getLength();j++)
{
Node property = idList.item(j);
String name = property.getNodeName();
if (name.equalsIgnoreCase("word"))
{
//Read your values here
Log.e("",property.getFirstChild().getNodeValue());
}
if (name.equalsIgnoreCase("meaning"))
{
//Read your values here
Log.e("",property.getFirstChild().getNodeValue());
}
}
}

Is there anything like NSDictionary in android?

I'm new to Android. I did search around but couldn't find anything work like NSdictionary of iOS in Android. For example in iOS I can create SIMPLE array of dictionary like this format
Array
idx1: [objA1 for keyA],[objB1 for keyB],[objB1 for keyC]
idx2: [objA2 for keyA],[objB2 for keyB],[objB2 for keyC]
idx3: [objA3 for keyA],[objB3 for keyB],[objB3 for keyC]
I know I can create string-array that work similar like that in android
<string-array name="list_obj1">
<item>ObjA1</item>
<item>ObjB2</item>
<item>ObjC3</item>
</string-array>
<string-array name="list_obj2">
<item>ObjB1</item>
<item>ObjB2</item>
<item>ObjB3</item>
</string-array>
<string-array name="list_obj3">
<item>ObjC1</item>
<item>ObjC2</item>
<item>ObjC3</item>
</string-array>
My question is if there is anything else used to create AN array of dictionary in Android like iOS.
Thank you for your help.
First, I think there are many tutorial about this stuff then you can search for more info.
Since you are new to android you might not know the "name" to search. For this case, "HashMap" is what you looking for. It works like NSdictionary.
//Create a HashMap
Map <String,String> map = new HashMap<String,String>();
//Put data into the HashMap
map.put("key1","Obj1");
map.put("key2","Obj2");
map.put("key3","Obj3");
// Now create an ArrayList of HashMaps
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
//Add the HashMap to the ArrayList
mylist.add(map);
Now you have st like an array of dictionary.
Hope this help.
You could put what #user1139699 said into an ArrayList.
ArrayList<HashMap> list = new ArrayList();
Map <String, String> map = new HashMap<String,String>();
map.put("key","Obj");
list.add(map);
also if you want to load a file like this:
property.key.1=value of 1st key
property.key.2=value of 2nd key
prompt.alert = alert
etc you may use java Properties(); Then you can instantly get the value of each key.
Explanation:
You have for example a file myTranslations.txt . In that file you write pairs of keys/values in the format:
property.key.1=value of 1st key
property.key.2=value of 2nd key
prompt.alert = alert
where the part before the "=" is the key, and the part after is the value.
Then in your code you do:
Properties properties = new Properties();
File propertiesFile = new File (filePath);
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(propertiesFile);
properties.load(inputStream);
} catch (IOException ioe) {
ioe.printStackTrace();
}
where filePath is the path to file above.
Then you can get the value of each key as:
properties.get("prompt.alert")
which will return the string:
alert
as it is in the txt file.
If it helps please upvote.

submitting data to an array to be pulled later

So I've got the following:
NodeList nodeList = element.getElementsByTagName("rowset");
if (nodeList.getLength() > 0) {
for (int i = 0; i < nodeList.getLength(); i++) {
Element entry = (Element) nodeList.item(i);
Element _titleE = (Element) entry.getElementsByTagName("row").item(0);
Node _title = _titleE.getAttributes().getNamedItem("name");
t1.setText(_title.getNodeValue());
}
}
I've got the following XML layout:
<row name="" characterID="" corporationName="" corporationID="" />
(couple of lines of these)
the ideal way would be to create an array right? and then call the data from the array?
EDIT:
What I'm trying to do is read an XML File and store the values so that they can be accessed later so I'm assuming the ideal way would be to use an array?
(as my girlfriends name is jenny, too, I will be guessing what you want)
If you just want to store one value, an array or a ArrayList is good for that. If you need to store all 4 given attributes of your row, you should think about creating a class (lets call it MyRow) that contains those values. Than you can put all your rows into one ArrayList with the type of your class.
Pseudocode:
ArrayList<MyRow> myRowList = new ArrayList<MyRow>();
while reading each row
MyRow row = new MyRow();
row.mName = getAttributes().getNamesItem("name");
row.mCharacterId = getAttributes().getNamesItem("characterID");
// more setting...
}
A last tip for the next time: take some time to explain and specify your next question. That will improve the answers you get as well.

Categories

Resources