Basically I'm creating an android game and want to save some data for levels in an XML file which are saved in assets folder and I parse them like :
final SAXParserFactory spf = SAXParserFactory.newInstance();
final SAXParser sp = spf.newSAXParser();
final XMLReader xmlReader = sp.getXMLReader();
final XMLParser pXMLParser = new XMLParser();//My own created Class
xmlReader.setContentHandler(pXMLParser);
InputStream inputStream = Z.act.getAssets().open("levels/" + PackName + ".xml");
xmlReader.parse(new InputSource(new BufferedInputStream(inputStream)));
return pXMLParser.getParsedLevel();
Things were right until then, I was successfully able to create and save XML files. But not too much, I also wanted to create a level editor. I was able to create the XML
(in String datatype) by just using something like
(there are various "String +=" in different methods based upon call from the level editor activity/scene):
String XMLString = "";
XMLString += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
....
XMLString += " </" + tagEnemy + ">"; // tagEnemy is a variable string I created
And I am pretty confused now If this is correct Or how should I create this dynamically in XML form (or any convinient form) and where to save(probably internal or external storage in android) should be best.Since I tried many code Fragments from finding many things on google much of my code after this may be useless and not working, but if you say i can add it.Thanks for your Help.
try my code it parse the data from asset/url
public class SaxParserTest extends DefaultHandler {
Boolean currentElement = false;
String currentValue = null;
ArrayList<HashMap<String, Object>> datalist = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> temp;
public ArrayList<HashMap<String, Object>> getData(Context context ){
try {
SAXParserFactory saxparser = SAXParserFactory.newInstance();
SAXParser parser = saxparser.newSAXParser();
XMLReader xmlReader = parser.getXMLReader();
xmlReader.setContentHandler(SaxParserTest.this);
/*
* used when pick local data
*/
// InputStream is =context.getAssets().open("data.xml");
// xmlReader.parse(new InputSource(is));
/*
* used when pick data from url
*/
URL url = new URL("http://www.xmlfiles.com/examples/cd_catalog.xml");
xmlReader.parse(new InputSource(url.openStream()));
} catch (Exception e) {
e.getMessage();
}
return datalist;
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if (localName.equalsIgnoreCase("CD")) {
temp=new HashMap<String, Object>();
temp.put(Constant.id, attributes.getValue(Constant.id));
// temp.put(Constant.title, attributes.getValue(Constant.title));
// temp.put(Constant.artist, attributes.getValue(Constant.artist));
// temp.put(Constant.country, attributes.getValue(Constant.country));
// temp.put(Constant.company, attributes.getValue(Constant.company));
// temp.put(Constant.price, attributes.getValue(Constant.price));
// temp.put(Constant.year, attributes.getValue(Constant.year));
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
currentValue = new String(ch, start, length);
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
if(localName.equals(Constant.title))
temp.put(Constant.title, currentValue);
if(localName.equals(Constant.artist))
temp.put(Constant.artist, currentValue);
if(localName.equals(Constant.country))
temp.put(Constant.country, currentValue);
if(localName.equals(Constant.company))
temp.put(Constant.company, currentValue);
if(localName.equals(Constant.price))
temp.put(Constant.price, currentValue);
if(localName.equals(Constant.year))
temp.put(Constant.year, currentValue);
if(localName.equalsIgnoreCase("CD"))
datalist.add(temp);
Log.i("DataList", datalist.toString());
}
}
and use this like that
SaxParserTest test=new SaxParserTest();
datal=test.getData(this);
SimpleAdapter adapter = new SimpleAdapter(MainActivity.this, datal,
R.layout.activity_main, new String[] { Constant.title,
Constant.artist, Constant.price, Constant.year,
Constant.company, Constant.country ,Constant.id}, new int[] {
R.id.txt1, R.id.txt2, R.id.txt3, R.id.txt4,
R.id.txt5, R.id.txt6 ,R.id.txt7});
setListAdapter(adapter);
Related
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) {
elementOn = true;
if (localName.equals("DEAL")) {
discount = new Discount();
}
}
#Override
public void endElement(String uri, String localName, String qName){
elementOn = false;
if(localName.equalsIgnoreCase("IMAGE")) {
discount.setImage(elementValue);
} else if(localName.equalsIgnoreCase("DEAL")) {
arrayDiscount.add(discount);
}
}
#Override
public void characters(char[] ch, int start, int length){
if (elementOn) {
elementValue = new String(ch, start, length);
elementOn = false;
}
}
and then input looks like (I paste only the a few lines, there is also many lines before and after, many, objects" containing IMAGE, PRICES and other tags)
<IMAGE>http://www.url.com/1815/e0deb0bcca75704ef974d017028563f401386541247.jpg</IMAGE>
<FINAL_PRICE>24.9</FINAL_PRICE>
<ORIGINAL_PRICE>49</ORIGINAL_PRICE>
when I then put to console output from the arrays of discounts and get image url, it gives me sometimes only parts of that string like
http://www.url.com/1815/e0deb0bcc
IT happened only in long text between open and enclosing tags
Here is also connecting SaxParser
SAXParserFactory saxPF = SAXParserFactory.newInstance();
SAXParser saxP = saxPF.newSAXParser();
XMLReader xmlR = saxP.getXMLReader();
URL url = new URL("http://www.url.com/output.xml");
XMLHandler myXMLHandler = new XMLHandler();
xmlR.setContentHandler(myXMLHandler);
xmlR.parse(new InputSource(url.openStream()));
Im using Sax Parser because it is the fastes from the native classes of Android.
Thank you
The SAX interface allows a parser to break a text node up into multiple pieces and supply the pieces in multiple calls of the characters() method. Your code is not allowing for this possibility. The parser is allowed to break the text anywhere, but it is common practice to break it in places where the text content is not contiguous in the input, e.g. at entity boundaries.
i'm trying to parse rss feed in my android app.
and my feed contains a lot of items with tags "tag"
it looks like
<item>
<title> title </title>
<link> link </link>
<pubDate> date </pubDate>
<description> description </description>
<tags>
<tag id="1">first</tag>
<tag id="2">second</tag>
<tag id="3">third</tag>
</tags>
</item>
my question:
how can i select items only with specific "tag" eg. tag="second'?
rewrote a Xml Factory class I had, it should lead you on the right track.
/**
*
* #author hsigmond
*
*/
public class RssXmlFactory {
public static ArrayList<RSSItem> parseResult(final String rssDataContent,String tag_id) throws ParserConfigurationException,
SAXException, IOException {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
public String mItemTagID=tag_id;//"2"
RSSItemsHandler parser = new RSSItemsHandler();
xr.setContentHandler(parser);
StringReader sr = new StringReader(rssDataContent);
InputSource is = new InputSource(sr);
xr.parse(is);
return parser.mItemList;
}
}
class RSSItemsHandler extends DefaultHandler {
private StringBuilder mSb = new StringBuilder();
public ArrayList<RSSItem> mItemList = new ArrayList<RSSItem>();
public RSSItem mCurrentRssItem = null;
public String mItemTitle="";
#Override
public void startElement(final String namespaceURI, final String localName, final String qName,
final Attributes atts) throws SAXException {
mSb.setLength(0);
if (localName.equals(XMLTag.TAG_RSS_ITEM_ROOT)) {
/** Get the rss item title attribute value */
mItemTitle=atts.getValue(XMLTag.TAG_RSS_ITEM_TITLE);
//#TODO Log result
}
else if (localName.equals(XMLTag.TAG_RSS_ITEM_TAG_ROOT)) {
//This is where you check if the TAG equals id=2, did not have the time to check if it works yet, it's late...
if(atts.getValue(XMLTag.TAG_RSS_ITEM_TAG_ID).equalsIgnoreCase(mItemTagID)){//id="2"
mCurrentRssItem = new RSSItem();
/** Set item title attribute value */
mCurrentRssItem.title=mItemTitle;
//#TODO Log result
}
}
}
#Override
public void endElement(final String namespaceURI, final String localName, final String qName) throws SAXException {
if (localName.equals(XMLTag.TAG_RSS_ITEM_ROOT)) {
mItemList.add(mCurrentRssItem);
} else if (localName.equals(XMLTag.TAG_RSS_ITEM_TAG_ROOT)) {
mCurrentRssItem.tag = mSb.toString();
}
}
#Override
public void characters(final char[] ch, final int start, final int length) throws SAXException {
super.characters(ch, start, length);
mSb.append(ch, start, length);
}
}
}
For more details on how to handle XML on Android look here: http://www.ibm.com/developerworks/opensource/library/x-android/index.html
I am trying to parse a RSS feed using SAX parser
This is my code:
public class MainActivity extends Activity {
ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();
ListView list;
ArrayList<String> sinlgeItem = null;
ProgressDialog pd;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list=(ListView)findViewById(R.id.list);
boolean b=parseData();
Log.v("result", "value"+b);
for(int i=0;i<data.size();i++){
Log.e("ITEM",data.get(i).get(0)+"__"+data.get(i).get(1));
}
}
/**
* method parse the data
*/
private boolean parseData() {
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
URL url = new URL("https://itunes.apple.com/WebObjects/MZStore.woa/wpa/MRSS/newreleases/sf=143441/limit=25/rss.xml");
xr.setContentHandler(new MyHandler());
xr.parse(new InputSource(url.openStream()));
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public class MyHandler extends DefaultHandler{
Boolean ITEM=false;
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
}
#Override
public void endElement(String uri, String localName, String name) throws SAXException {
super.endElement(uri, localName, name);
if (ITEM){
RootElement root=new RootElement("rss");
Element chan=root.getChild("channel");
Element itms=chan.getChild("item");
Element title=itms.getChild("title");
Element artist=itms.getChild("http://phobos.apple.com/rss/1.0/modules/itms/", "artist");
title.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
sinlgeItem.add(body);
Log.v("title",body);
}
});
artist.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
sinlgeItem.add(body);
Log.v("artist", body);
}
});
ITEM=false;
data.add(sinlgeItem);
}
}
#Override
public void startDocument() throws SAXException {
super.startDocument();
}
#Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
if (localName.equals("item")){
sinlgeItem = new ArrayList<String>();
ITEM=true;
}
}
}
}
This is the link to the xml feed
https://itunes.apple.com/WebObjects/MZStore.woa/wpa/MRSS/newreleases/sf=143441/limit=25/rss.xml
I am trying to parse the title element with in the item tag and the element itms:artist with in the item tag.
I don't know how to handle tags with name spaces
Refer the following example's
Example on RSSFeed parsing
Simple RSSReader example
Complete guide on Reading RSS Feeds
Display news&videos through RSSFeeds
I don't think you should use SAXParser for parsing RSS. It would be easier using XML Pull Parser. I would choose to SAXParser for parsing a continuous client-server communication like XMPP Protocol since SAX is best for for parsing incomplete and continuous XML.
I have a problem when parsing xml from the internet. The parser doesn't return all the data correctly.
Three are three errors:
correct result -->return result
161:1:161-->1:1:161
330:2:132-->3:2:132
421:2:223-->4:2:223
Copy of the xml file I am trying to parse
https://docs.google.com/open?id=0BwXEx9yI14inT1BnR2xzYnJEX0E
Activity
public class DataBaseUpdateService_1 extends Activity {
private TextView TextView1 ;
private LinearLayout linearlayout1 ;
private TextView title[];
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_item);
linearlayout1 = (LinearLayout)findViewById(R.id.linearlayout1);
TextView1 = (TextView)findViewById(R.id.textView1);
MyDBHelper dbHelper =new MyDBHelper(DataBaseUpdateService_1.this);
SQLiteDatabase db = dbHelper.getWritableDatabase();
try {
/** Handling XML */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Send URL to parse XML Tags */
URL sourceUrl = new URL(
"http://123.com/example.xml");
/** Create handler to handle XML Tags ( extends DefaultHandler ) */
DataBaseUpdate_XMLHandler XMLHandler = new DataBaseUpdate_XMLHandler();
xr.setContentHandler(XMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
}catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
int itemCount = DataBaseUpdate_XMLHandler.array.size();
db.delete("hymns_match", null, null);
try{
for(int i=0;i<itemCount;i++) {
String songs_id=DataBaseUpdate_XMLHandler.array.get(i).get("songs_id");
String songs_book_id=DataBaseUpdate_XMLHandler.array.get(i).get("songs_book_id");
String songs_book_ch=DataBaseUpdate_XMLHandler.array.get(i).get("songs_book_ch");
TextView tv = new TextView(DataBaseUpdateService_1.this);
tv.setText(songs_id + ":"+songs_book_id+ ":"+songs_book_ch);
linearlayout1.addView(tv);
}
}catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
}
}
DataBaseUpdate_XMLHandler
public class DataBaseUpdate_XMLHandler extends DefaultHandler {
Boolean currentElement = false;
String currentValue=null;
static ArrayList<LinkedHashMap<String, String>> array;
LinkedHashMap map;
#Override
public void startDocument() throws SAXException {
array = new ArrayList<LinkedHashMap<String, String>>();
}
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentElement = true;
if (localName.equals("song")) {
map = new LinkedHashMap<String, Object>();
currentValue=null;
}
/*Get attribute
* else if (localName.equals("website")) {
* String attr = attributes.getValue("category");
* sitesList.setCategory(attr);}
* */
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
currentElement = false;
/** set value */
if (localName.equalsIgnoreCase("songs_id")){
map.put("songs_id",currentValue);}
else if (localName.equalsIgnoreCase("songs_book_id")){
map.put("songs_book_id", currentValue);}
else if (localName.equalsIgnoreCase("songs_book_ch")){
map.put("songs_book_ch", currentValue);}
else if (localName.equalsIgnoreCase("song")){
array.add(map);}
}
/** Called to get tag characters
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (currentElement) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}
}
Can you give some advice about what's wrong here?
According to the SAX definition characters() method can be called multiple times per elements. So it should accumulate the text; if this is happening then your code will not work.
I have a XML file in assets folder.
I am parsing it in my Activity and displaying it.
In XML file I has a data with < symbol, I use < at < symbol.
But, the symbol is not displying and text after the symbol only i am getting.
ex "hi < hello"
parsing result will be only hello
parsing code
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
SecondHandler shandler = new SecondHandler();
xr.setContentHandler(shandler);
InputStream in = this.getAssets().open(fileName);
xr.parse(new InputSource(in));
itemlist = shandler.getParsedData();
} catch (Exception e) {
System.out.println("Error : " + e);
}
Map<String, String> item = (Map<String, String>) list.get(5);
String qus = item.get("question");
String ans = item.get("answer");
}
xml file..
..........
<dict>
<question>hello</question>
<answer>I am < 5 you</answer>
</dict>
......
handler code.
public class SecondHandler extends DefaultHandler {
private String tagName;
#SuppressWarnings("rawtypes")
private ArrayList<Map> dataSet;
private Map<String, String> dictionary;
#SuppressWarnings("rawtypes")
public ArrayList<Map> getParsedData() {
return dataSet;
}
#Override
public void startDocument() throws SAXException {
}
#Override
public void endDocument() throws SAXException {
// Nothing to do
}
#SuppressWarnings("rawtypes")
#Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
tagName = localName;
if (localName.equals("array")) {
this.dataSet = new ArrayList<Map>();
} else if (localName.equals("dict")) {
dictionary = new HashMap<String, String>();
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("array")) {
} else if (localName.equals("dict")) {
dataSet.add(dictionary);
}
}
#Override
public void characters(char ch[], int start, int length) {
String string = new String(ch, start, length);
string = string.replaceAll(" ", "");
string = string.replaceAll("\n", "");
string = string.replaceAll("\t", "");
if (string.length() > 0 && string != null) {
dictionary.put(tagName, new String(ch, start, length));
// System.out.println("Dictionary : " + dictionary);
}
}
}
How to solve this problem
Thanks in advance...!
A SAX parser can supply character data to the ContentHandler in as many calls of the characters() method as it chooses. Your characters() method is putting each of the substrings in the same hashtable entry, overwriting any previous substrings; you need to concatenate them.
may be you directly use "<" in xml file write ,
So use Value-->String class
==>string name="temperature_lt" value is= Temperature & l t;(Note here ignore space)
and extractin xml file
==>android:text="#string/temperature_lt"
try it,