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);
}
}
}
Related
I am creating the recovery of text using XML from a URL. I get the text. But I have a problem.
When the text of an item of the XML is large, in the TextView not shows all text of the XML.
What can be the error?
ACTIVITY
class tareaAsyncHorariosTarifas extends AsyncTask<Void, Void, Void> {
XmlReader helper;
#Override
protected Void doInBackground(Void... params) {
helper = new XmlReader(color);
helper.get();
return null;
}
#Override
protected void onPostExecute(Void result) {
StringBuilder builder = new StringBuilder();
for (HorariosTarifasObj post : helper.posts) {
builder.append(post.getHorarios());
}
if(builder.toString().equals("")) {
horario2.setText("-");
} else {
horario2.setText(Html.fromHtml(builder.toString()));
}
builder = new StringBuilder();
for (HorariosTarifasObj post : helper.posts) {
builder.append(post.getTarifas());
}
if(builder.toString().equals("")) {
tarifa2.setText("-");
} else {
tarifa2.setText(Html.fromHtml(builder.toString()));
}
}
}
XML READER
public XmlReader(String color) {
this.color = color;
}
public void get() {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
reader.setContentHandler(this);
InputStream inputStream = new URL(URL + color + ".xml").openStream();
reader.parse(new InputSource(inputStream));
} catch (Exception e) {
}
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currTag = true;
currTagVal = "";
if (localName.equals("color")) {
post = new HorariosTarifasObj();
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
currTag = false;
if(localName.equalsIgnoreCase("horarios")) {
post.setHorarios(currTagVal);
} else if(localName.equalsIgnoreCase("tarifas")) {
post.setTarifas(currTagVal);
} else if (localName.equalsIgnoreCase("color")) {
posts.add(post);
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (currTag) {
currTagVal = currTagVal + new String(ch, start, length);
currTag = false;
}
}
my XML Content: (FileName: sku.xml)
<skus>
<id>p1</id>
<id>test</id>
<id>aa</id>
<id>bb</id>
<id>cc</id>
<id>dd</id>
<id>ee</id>
<id>ff</id>
<id>gg</id>
<id>hh</id>
<id>ii</id>
<id>jj</id>
<id>kk</id>
<id>ll</id>
</skus>
my SAX XML PARSER Class:
public class SAXXMLParser {
public static List<XMLSetAdd> parse(InputStream is) {
List<XMLSetAdd> setAdds = null;
try {
// create a XMLReader from SAXParser
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser()
.getXMLReader();
// create a SAXXMLHandler
SAXXMLHANDLER saxHandler = new SAXXMLHANDLER();
// store handler in XMLReader
xmlReader.setContentHandler(saxHandler);
// the process starts
xmlReader.parse(new InputSource(is));
// get the News list`
setAdds = saxHandler.getIds();
} catch (Exception ex) {
Log.d("XML", "SAXXMLParser: parse() failed");
ex.printStackTrace();
}
// return News list
return setAdds;
}
}
My SAX XML HANDLER:
public class SAXXMLHANDLER extends DefaultHandler {
private List<XMLSetAdd> setAdds;
private String tempVal;
// to maintain context
private XMLSetAdd setAdd;
public SAXXMLHANDLER() {
setAdds = new ArrayList<XMLSetAdd>();
}
public List<XMLSetAdd> getIds() {
return setAdds;
}
// Event Handlers
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equals("skus")) {
setAdd = new XMLSetAdd();
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
tempVal = new String(ch, start, length);
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equals("skus")) {
setAdds.add(setAdd);
} else if (qName.equals("id")) {
setAdd.setId(tempVal);
}
}
}
my XML SetAdd:
public class XMLSetAdd {
public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
}
private String Id;
}
My Async Class:
private class GetXMLTask extends AsyncTask<String, Void, List<XMLSetAdd>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(List<XMLSetAdd> news) {
try
{
for (int i = 0; i < IdsL.size(); i++)
{
skusList.add(IdsL.get(i).getId());
Log.d("XML content",IdsL.get(i).getId());
}
skusQuery = new Bundle();
skusQuery.putStringArrayList("ITEM_ID_LIST", skusList);
GetAllSkusAsync runner = new GetAllSkusAsync();//Some Async to run after
runner.execute();
}
catch (Exception ex)
{
Log.d("Error Reading XML: ", ex.toString());
Toast.makeText(
getApplicationContext(),"Connection Error!"
Toast.LENGTH_SHORT).show();
}
}
/*
* uses HttpURLConnection to make Http request from Android to download
* the XML file
*/
private String getXmlFromUrl(String urlString) {
StringBuffer output = new StringBuffer("");
try {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
}
} catch (Exception ex) {
Log.d("Error in asyncTask XML: ", ex.toString());
ex.printStackTrace();
}
return output.toString();
}
private List<XMLSetAdd> IdsL;
#Override
protected List<XMLSetAdd> doInBackground(String... urls) {
IdsL = null;
List<XMLSetAdd> myList = null;
String xml = null;
for (String url : urls) {
xml = getXmlFromUrl(url);
InputStream stream = new ByteArrayInputStream(xml.getBytes());
IdsL = SAXXMLParser.parse(stream);
myList = SAXXMLParser.parse(stream);
}
// stream.close();
return IdsL;
}
}
The code which I use to call Async Class:
String URL = "http://someaddress/php/sku.xml";
GetXMLTask task = new GetXMLTask();
task.execute(new String[] { URL });
Now When I run this code and Log the result ,my list returns the last xml child which based on my xml file is "ll" and the rest of xml is not added to the file.
The list should return all of the ids but returns the last one.
Check following code. Edited SAX XML HANDLER.
public class SAXXMLHANDLER extends DefaultHandler {
private List<XMLSetAdd> setAdds;
private String tempVal;
// to maintain context
private XMLSetAdd setAdd;
public SAXXMLHANDLER() {
}
public List<XMLSetAdd> getIds() {
return setAdds;
}
// Event Handlers
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equals("skus")) {
setAdds = new List<XMLSetAdd>();
}else if(qName.equals("id")){
setAdd = new XMLSetAdd();
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
tempVal = new String(ch, start, length);
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (qName.equals("skus")) {
} else if (qName.equals("id")) {
setAdd.setId(tempVal);
setAdds.add(setAdd);
}
}
}
The reason is because you are only adding items to the list when endElement is skus. You should be adding one element for each id as follows:
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("skus")) {
// setAdds.add(setAdd); // dont add here..
} else if (qName.equals("id")) {
setAdd.setId(tempVal); // if ending with id
setAdds.add(setAdd); // then add id to the list
}
}
Update
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// reset
tempVal = "";
if (qName.equals("id")) {
setAdd = new XMLSetAdd(); // new item for each id
}
}
#Override
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
curentElement=localName;
if(qName.equals("skus")){
setAdd = new XMLSetAdd();
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
String value = new String(ch, start, length);
if(curentElement.equals("id")){
tempVal=value;
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
curentElement = "";
if (localName.equals("id")) {
setAdd.setId(tempVal);
}else if(localName="skus"){
setAdds.add(setAdd);
}
Try this way
Update your parse
public class SAXXMLHANDLER extends DefaultHandler {
private List<XMLSetAdd> setAdds;
private String tempVal;
// to maintain context
private XMLSetAdd setAdd;
public SAXXMLHANDLER() {
setAdds = new ArrayList<XMLSetAdd>();
}
public List<XMLSetAdd> getIds() {
return setAdds;
}
// Event Handlers
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// reset
if (qName.equals("id")) {
tempVal = "";
setAdd = new XMLSetAdd();
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
tempVal = new String(ch, start, length);
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("id")) {
setAdd.setId(tempVal);
setAdds.add(setAdd);
}
}
I have an XML file I am reading in via SAXParser, but I am having trouble reading it in correctly. The XML is structured like this:
<game>
<players>
<player>
<name>Player 1</name>
<score>100</score>
</player>
</players>
</game>
How can I get the Android SAXParser to read the values between tags? This is the code that I have, but it is looking for an attribute to the tag, not the text between.
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(localName.equals("name")) {
names.add(attributes.getValue("name"));
}
else if(localName.equals("score")) {
scores.add(Integer.parseInt(attributes.getValue("score")));
}
}
Drawing from the example #
http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/
More info about sax #
http://docs.oracle.com/javase/tutorial/jaxp/sax/parsing.html
Apart from sax you should have a look at xmllpullparser which is recommended.
Quoting from the docs.
We recommend XmlPullParser, which is an efficient and maintainable way to parse XML on Android.
Check the link #
http://developer.android.com/training/basics/network-ops/xml.html
public void readxml(){
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean bname = false;
boolean bscore = false;
public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("name")) {
bname = true;
}
if (qName.equalsIgnoreCase("score")) {
bscore = true;
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
}
public void characters(char ch[], int start, int length) throws SAXException {
if (bname) {
Toast.makeText(getApplicationContext(), new String(ch, start, length), 10000).show();
bname = false;
}
if (bscore) {
Toast.makeText(getApplicationContext(), new String(ch, start, length), 10000).show();
bscore = false;
}
}
};
saxParser.parse("myxmltoparse", handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}
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?
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,