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,
Related
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);
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 problem with encoding. To begin with perhaps a bit of code:
URL xmlUrl = new URL("http://helion.pl/rss/GW/promocje.rss");
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser parser = saxFactory.newSAXParser();
XMLReader reader = parser.getXMLReader();
Helion xmlHandler = new Helion();
reader.setContentHandler(xmlHandler);
InputSource inputSource = new InputSource(xmlUrl.openStream());
inputSource.setEncoding("ISO-8859-1");
reader.parse(inputSource);
The file is encoded ISO-8859-2, but when I use setEncoding("ISO-8859-2") file is not read. Please help.
DefaultHandler:
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTagName = qName;
if (TAG_ITEM.equalsIgnoreCase(qName)) {
odczyt = true;
element = new Element();
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String value = new String(ch, start, length);
if (!value.trim().equals("")) {
if (odczyt) {
if (TAG_TYTOL.equalsIgnoreCase(currentTagName)) {
element.setTytol(value);
} else if (TAG_OPIS.equalsIgnoreCase(currentTagName)) {
element.setOpis(value);
}
}
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (TAG_ITEM.equalsIgnoreCase(localName)) {
odczyt = false;
elementy.add(element);
}
}
}
As Francis Upton mentions, characters can be called multiple times within one XML start/end element.
You should do something like this:
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String s = new String(ch, start, length);
if (mTextBuffer == null) {
mTextBuffer = new StringBuffer(s);
} else {
mTextBuffer.append(s);
}
}
And then call element.setTytol(mTextBuffer)/element.setOpis(mTextBuffer) in your endElement method
In your code you are setting it to ISO-8859-1 which is very different, could that be the problem?
My project downloads lots of xml (as text) and images then I parse the xml and interpret the data there. When I check some of the xml downloaded some of them are getting truncated only showing a partial part of it. The beginning parts of it is gone. I use:
InputStream in;
in = OpenHttpConnection(url);
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(this);
xr.parse(new InputSource(in));
Edited:
#Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
if (localName.equals("quiz") ) {
parsedQuizTitle = new QuizTitle();
in_quiztitle = true;
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("category") || localName.equals("quiz") ) {
in_quiztitle = false;
quiztitleSet.add(parsedQuizTitle);
}
}
#Override
public void characters(char ch[], int start, int length) {
if (in_quiztitle) {
String quiz_item = new String(ch, start, length);
String[] quiz_item_parsed = null;
String expression = "\\|\\|";
quiz_item_parsed = quiz_item.split(expression);
if(quiz_item_parsed.length == 2) {
parsedQuizTitle.setQuizTitleName(quiz_item_parsed[1]);
parsedQuizTitle.setQuizTitleID(quiz_item_parsed[0]);
}
else {
//add to title
parsedQuizTitle.addtoQuizTitleName(quiz_item);
}
}
}
So I've got to parse ugly files that contain nested tags like
<p>blah<strong>lah</strong>blah</p>
The nested tags are defined and I don't care about them. But they make XmlPullParser fail:
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(some_reader);
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (XmlPullParser.START_TAG == event) {
String tag = parser.getName();
if (tag != null) {
tag = tag.toLowerCase();
} else {
continue;
}
if ("p".equals(tag)) {
String text = parser.nextText();
// and here we go
// org.xmlpull.v1.XmlPullParserException: expected: /p read: strong
}
}
}
Question: any chance I could get away w/o preprocessing the file stripping all the unnecessary tags or using a third-party library?
EDIT:
Updated the snippet to actually make sense.
So I've got rid of XMLPullParser and switched to SAXParser. Besides, it performs better.
package com.xml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
public class FeedHandler extends DefaultHandler {
StringBuilder sb = null;
String ret = "";
boolean bStore = false;
int howMany = 0;
FeedHandler() { }
String getResults()
{
return "XML parsed data.\nThere are [" + howMany + "] status updates\n\n" + ret;
}
#Override
public void startDocument() throws SAXException
{
// initialize "list"
}
#Override
public void endDocument() throws SAXException
{
}
#Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
try {
if (localName.equals("status"))
{
this.sb = new StringBuilder("");
bStore = true;
}
if (localName.equals("user"))
{
bStore = false;
}
if (localName.equals("text"))
{
this.sb = new StringBuilder("");
}
if (localName.equals("created_at"))
{
this.sb = new StringBuilder("");
}
} catch (Exception e)
{
Log.d("error in startElement", e.getStackTrace().toString());
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException
{
if (bStore)
{
if (localName.equals("created_at"))
{
ret += "Date: " + sb.toString() + "\n";
sb = new StringBuilder("");
return;
}
if (localName.equals("user"))
{
bStore = true;
}
if (localName.equals("text"))
{
ret += "Post: " + sb.toString() + "\n\n";
sb = new StringBuilder("");
return;
}
}
if (localName.equals("status"))
{
howMany++;
bStore = false;
}
}
#Override
public void characters(char ch[], int start, int length)
{
if (bStore)
{
String theString = new String(ch, start, length);
this.sb.append(theString);
}
}
}
and this my xmlActivity class that extend Activity
InputSource is = new InputSource(getResources().openRawResource(R.raw.my));
System.out.println("running xml file..... ");
// create the factory
SAXParserFactory factory = SAXParserFactory.newInstance();
// create a parser
SAXParser parser = factory.newSAXParser();
// create the reader (scanner)
XMLReader xmlreader = parser.getXMLReader();
// instantiate our handler
FeedHandler fh = new FeedHandler();
// assign our handler
xmlreader.setContentHandler(fh);
// perform the synchronous parse
xmlreader.parse(is);
// should be done... let's display our results
tvData.setText(fh.getResults());