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?
Related
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 am doing an Android application. In my app I have to parse a xml page.The data in the xml page is in the following format.
<root>
<tag1>data</tag1>
<tag2>
<div>data1</div><div>data2</div>
</tag2>
</root>
to tried to take data through sax parsing.
if (localName.equalsIgnoreCase("tag1"))
if (localName.equalsIgnoreCase("tag2"))
But I am not getting any data from tag2 but getting value from tag1.I want to get all data include div tag also then only i can show data in like html page.
Use this sample code
public class SAXParserDemo extends DefaultHandler {
private String currentTag = "";
private StringBuffer responseTag;
private String str;
#Override
public void startDocument() throws SAXException {
super.startDocument();
}
#Override
public void endDocument() throws SAXException {
super.endDocument();
}
#Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, name, attributes);
currentTag = localName;
if ("tag1".equalsIgnoreCase(localName)) {
responseTag = new StringBuffer();
}else if ("tag2".equalsIgnoreCase(localName)) {
responseTag = new StringBuffer();
}else if ("div".equalsIgnoreCase(localName)) {
responseTag = new StringBuffer();
}
}
#Override
public void endElement(String uri, String localName, String name)
throws SAXException {
super.endElement(uri, localName, name);
String responseValue = responseTag.toString().trim();
if ("tag1".equalsIgnoreCase(localName)) {
Log.v("TAG", "Tag 1 value "+responseValue);
}else if ("tag2".equalsIgnoreCase(localName)) {
Log.v("TAG", "Tag 2 value "+responseValue);
}else if ("div".equalsIgnoreCase(localName)) {
Log.v("TAG", "div value "+responseValue);
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
str = new String(ch, start, length);
if ("tag1".equalsIgnoreCase(currentTag)) {
responseTag.append(str);
}else if ("tag2".equalsIgnoreCase(currentTag)) {
responseTag.append(str);
}else if ("div".equalsIgnoreCase(currentTag)) {
responseTag.append(str);
}
}
}
If you are using SAX parsing, you need to look for the div element and you need to keep track of the parent element (yourself) and make sure that's tag2. You are getting the data (characters) in the tag1 element because it directly contains those characters. The tag2 element does not contain any (non-whitespace) characters, only other elements.
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,
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);
}
}
}