Sax parser not getting full text, no unallowed or ampersand chars - android

#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.

Related

Creating ,Writing and Reading an XML File in Android

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);

While using sax parser for parsing an xml with '&' as a part of data, the parser breaks

I am using SAX parser for XML parsing when my XML contains tag like
<ServicePath>../Master/WebForm1.aspx?IsFirst=1&&</ServicePath>
<ServicePath>../FieldBook/ExportFieldBookData.aspx</ServicePath>
I am getting only "&" and "x" respectively in my database.How to solve this problem of parsing using SAX parser....
I had a similar problem, I could solve this by storing the data in the string builder and not string. Try this if you are using a string.
#Override
public void endElement(String uri, String localName, String qName)throws SAXException
{
currentElement = false;
if(localName.equalsIgnoreCase("title"))
{
header.add(sb);
}
if(localName.equalsIgnoreCase("description"))
{
desc.add(sb);
}
}
public void characters(char[] ch, int start, int length)throws SAXException
{
super.characters(ch, start, length);
Sb = new StringBuffer();
Sb.append(ch, start, length);
}
the header and the desc are my arrayists and the sb is my stringbuilder.

Parsing specific rss feed in android

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

SAX RSS FEED parser

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.

Android: Sax Reader, can't extract information needed

I am receiving a response from a XML request and I need to deal with it. The response will return either '00' when the request has been accepted and the account is verified and a '03' when the account is invalid.
Currently the Sax Reader is returning the correct information but I cannot extract the information from the reader so I can store the username / password into the internal storage of the phone.
The code from the Sax Reader is:
public void inputStreamToString(InputStream is) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean errorCode = false;
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("ErrorCode"))
{
errorCode = true;
}
}
public void endElement(String uri, String localName,String qName) throws SAXException
{
System.out.println("End Element :" + qName);
}
public void characters(char ch[], int start, int length) throws SAXException
{
if (errorCode)
{
System.out.println("ErrorCode : "+ new String(ch, start, length));
if (ch.equals(00))
{
System.out.println("IT WORKS!!!");
}
errorCode = false;
}
}
};
saxParser.parse(is, handler);
}
catch (Exception e)
{
System.out.println("Sax Error");
e.printStackTrace();
}
}
As you can see in the public void characters it is printing out the errorcode that is relevant from the response. I am currently trying to do ch.equals(00) in a If statement but it isn't picking out the correct information! Could it be a problem that ch is a char data type?
Any help will be appreciated.
I got it working. Instead of using '00' and '03' error codes. I have used the length of the response messages which are 'OK' and 'Invalid'.

Categories

Resources