Using saxParser, how can I tell when the endElement is complete? Unforunately I have a rather large XML file and need to store all my data into an ArrayList before passing it to the InsertHelper utility. How do I test if the saxParser has completed its looping?
/**
* Called when tag opening ( ex:- <name>AndroidPeople</name> -- <name> )
*/
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentElement = true;
if (localName.equals("StoreDetails")) {
//Log.i("TAG", "Store Details");
newKOPStoreVersion = attributes.getValue("stores_version");
//if (!dBHelper.getStoreXMLVersion().equals(newKOPStoreVersion)) { BUT BACK
Log.i("TAG", "Store Details Changed");
isStoreDetailsVersionChanged = true;
//dBHelper.deleteStoreDetail();
//currentValue = "";
//buffer = new StringBuffer();
dBHelper.setStoreXMLVersion(newKOPStoreVersion);
/*}
else BUT PACK
{
Log.i("TAG", "no change for KOP store version");
throw new KOPSAXTerminatorException();
}*/
}
}
/**
* Called when tag closing ( ex:- <name>AndroidPeople</name> -- </name> )
*/
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
currentElement = false;
//if (isStoreDetailsVersionChanged == true) { PUT BACK
if (localName.equals("StoreID")) {
buffer.toString().trim();
storeDetails.setStoreId(buffer.toString());
} else if (localName.equals("StoreName")) {
buffer.toString().trim();
storeDetails.setStoreName(buffer.toString());
} else if (localName.equals("StoreDescription")) {
buffer.toString().trim();
storeDetails.setStoreDescription(buffer.toString());
} else if (localName.equals("Location")) {
buffer.toString().trim();
storeDetails.setLocation(buffer.toString());
} else if (localName.equals("Phonenumber")) {
buffer.toString().trim();
storeDetails.setPhoneNumber(buffer.toString());
} else if (localName.equals("VisualmapID")) {
buffer.toString().trim();
storeDetails.setVisualMapId(buffer.toString());
} else if (localName.equals("x")) {
buffer.toString().trim();
storeDetails.setCartX(buffer.toString());
} else if (localName.equals("y")) {
buffer.toString().trim();
storeDetails.setCartY(buffer.toString());
} else if (localName.equals("ClosestParkingLot")) {
buffer.toString().trim();
storeDetails.setClosestParkingLot(buffer.toString());
} else if (localName.equals("RelatedCategory")) {
buffer.toString().trim();
storeDetails.setRelatedCategory(buffer.toString());
//add buffer to arraylist - then loop array do the ih dance
dataList.add(storeDetails);
//this is my arraylist and I'm attempting to loop over it outside of this class, but it seems to only contain the last value of the xml, not all the values.
}
buffer = new StringBuffer();
//}
if (localName.equals("StoreDetails")) {
//Log.i("TAG","End StoreDetails");
isStoreDetailsVersionChanged = false;
//throw new KOPSAXTerminatorException();
}
}
/**
* Called to get tag characters ( ex:- <name>AndroidPeople</name> -- to get
* AndroidPeople Character )
*/
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (currentElement) {
buffer.append(ch, start, length);
currentElement = false;
}
}
I can send you the complete code if you're willing to look at it.
End document gets called when the SAX parser is finished. All you have to do is override the method in your handler (the same class that has the element methods.
#Override
public void endDocument() throws SAXException {
}
Related
I have an Android app that parses XML using SAXParser. Everything goes ok, excepting some texts that get duplicated and trimmed. For example: "Just do it, even if you do not know how!" becomes " not know how!"
This is the DefaultHandler code. 10x!
DefaultHandler handler = new DefaultHandler()
{
Praise praise;
String elementValue = null;
Boolean elementOn = false;
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
if (localName.equals("praise"))
{
praise = new Praise();
elementOn = true;
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
// elementOn = false;
if (localName.equals("PRAISE_TEXT"))
{
praise.setPraiseText(elementValue);
}
if (localName.equals("MOOD"))
{
praise.setMood(elementValue);
}
if (localName.equals("RATING"))
{
praise.setRating(Integer.valueOf(elementValue));
}
if (localName.equals("praise"))
{
elementOn = false;
if (update)
{
if (database.getPraiseByText(praise.getPraiseText(), db) == null)
{
database.addPraise(db, praise.getPraiseText(), praise.getMood(),
Integer.valueOf(praise.getRating()));
}
}
else
database.addPraise(db, praise.getPraiseText(), praise.getMood(),
Integer.valueOf(praise.getRating()));
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException
{
// StringBuffer b = new StringBuffer();
if (elementOn)
{
elementValue = new String(ch, start, length);}}};
In SaxParsing, you do not have guarantee that characters will be called only once!
For this, you should concatenate all the characters you receive withing the same element
This is a just your code with a small modification. You should use StringBuilder instead of using String (:
DefaultHandler handler = new DefaultHandler()
{
Praise praise;
String elementValue = null;
Boolean elementOn = false;
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
elementValue = new String();
if (localName.equals("praise"))
{
praise = new Praise();
elementOn = true;
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (localName.equals("PRAISE_TEXT"))
{
praise.setPraiseText(elementValue);
}
if (localName.equals("MOOD"))
{
praise.setMood(elementValue);
}
if (localName.equals("RATING"))
{
praise.setRating(Integer.valueOf(elementValue));
}
if (localName.equals("praise"))
{
elementOn = false;
if (update)
{
if (database.getPraiseByText(praise.getPraiseText(), db) == null)
{
database.addPraise(db, praise.getPraiseText(), praise.getMood(),
Integer.valueOf(praise.getRating()));
}
}
else
database.addPraise(db, praise.getPraiseText(), praise.getMood(),
Integer.valueOf(praise.getRating()));
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException
{
// StringBuffer b = new StringBuffer();
if (elementOn)
{
elementValue = elementValue + new String(ch, start, length);
}
}
};
This problem often comes in SaxParsing. The Actual problem is it breaks the String by "/n" & only last part of String is available for us.
Now come to the solution, Take different booleans for tags(containing problems or for all).
In startElement method make relevent boolean true.
if (localName.equals("PRAISE_TEXT"))
{
isPrase= true'
praise.setPraiseText(elementValue);
}
in endElemet method make relevent boolean false.
if (localName.equals("PRAISE_TEXT"))
{
isPrase= false;
praise.setPraiseText(elementValue);
}
in characters method check for boolean like this:
if(isPrase)
{
elementValue = new String(ch, start, length);}}};
}
how can I parse XML like this
<rss version="0.92">
<channel>
<title>MyTitle</title>
<link>http://myurl.com</link>
<description>MyDescription</description>
<lastBuildDate>SomeDate</lastBuildDate>
<docs>http://someurl.com</docs>
<language>SomeLanguage</language>
<item>
<title>TitleOne</title>
<description><![CDATA[Some text.]]></description>
<link>http://linktoarticle.com</link>
</item>
<item>
<title>TitleTwo</title>
<description><![CDATA[Some other text.]]></description>
<link>http://linktoanotherarticle.com</link>
</item>
</channel>
</rss>
please any one help.
try this
public class ExampleHandler extends DefaultHandler {
private Channel channel;
private Items items;
private Item item;
private boolean inItem = false;
private StringBuilder content;
public ExampleHandler() {
items = new Items();
content = new StringBuilder();
}
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
content = new StringBuilder();
if(localName.equalsIgnoreCase("channel")) {
channel = new Channel();
} else if(localName.equalsIgnoreCase("item")) {
inItem = true;
item = new Item();
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(localName.equalsIgnoreCase("title")) {
if(inItem) {
item.setTitle(content.toString());
} else {
channel.setTitle(content.toString());
}
} else if(localName.equalsIgnoreCase("link")) {
if(inItem) {
item.setLink(content.toString());
} else {
channel.setLink(content.toString());
}
} else if(localName.equalsIgnoreCase("description")) {
if(inItem) {
item.setDescription(content.toString());
} else {
channel.setDescription(content.toString());
}
} else if(localName.equalsIgnoreCase("lastBuildDate")) {
channel.setLastBuildDate(content.toString());
} else if(localName.equalsIgnoreCase("docs")) {
channel.setDocs(content.toString());
} else if(localName.equalsIgnoreCase("language")) {
channel.setLanguage(content.toString());
} else if(localName.equalsIgnoreCase("item")) {
inItem = false;
items.add(item);
} else if(localName.equalsIgnoreCase("channel")) {
channel.setItems(items);
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
content.append(ch, start, length);
}
public void endDocument() throws SAXException {
// you can do something here for example send
// the Channel object somewhere or whatever.
}
}
where Item,Items and Channel are getter setter class ...
to know more visit this question How to parse XML using the SAX parser
I parsing the xml using sax parser in android. My xml structure is as given below
<customerlist>
<Customer>
<customerId>2</customerId>
<customerFname>prabhu</customerFname>
<customerLname>kumar</customerLname>
<customerImage>
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
</customerImage>
</Customer>
</customerlist>
I am able to get customerId, customerFname, customrLname, but for customerImage I am not getting complete string I am only getting part of the string i.e (iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAACJ9JREFUaIHtmllsXFcZx3/n3Due8XgcO3a8xG72tGkTknRJG7qAaEtbhFjVJUpBoBahgkoRUCFe+lCJvkAKCGgFPJQK0VKWqIhShMhL0mahLU1ImjZp0ziZLN5dezxje5Z7z/l4uDOOl9mcOskLf+vTle79fM63nPM/53xn4P+4tFDzrDffkEoKpQxTgAZcoCYvzpT3FxKWwHAD5PLiT3k/DW6JRjQQAupuuadx/VWbYk9b5dcg+uJkQlnR4uaOvjn28J7ticPAOOARODVdtUQTYaDu+7/86GONLfqbvvUiF9DcknB1KJMYtL/a9shrTxA4kWNGFkploAaoa1+t7mxfWhcRqTgULwiUUpG+02N3Aj8jyEBupk4xBxRBBmLJVEqiEznEWgBEBI8MYVVbdHYpFEZ8tNIUT65CrAEFSjmAxZcsIRUp3p7WJFNZAWJAOi/+VJ1SE9IBQmKsgwGsAgth3cCVTZ9FRIFViBXESjC9rCKTG+MjLfcRdRZjJ7+d0/P8LEsab6YxshxjfMK6gU9f/hS+tfk+ZogBMdYhmI8FEpmGcpO4xs8pba1grQCWzcsfYVH0ckbHexkcP8K1nV+jNbaWfad+zliml8+seYpoaCEnh3ZzZfMXuKzhBg50P8v69nuJ1SzmpSPfwPiGnJ+jM7aZtW1fpCW6FusJ6Nk50Br8nNIEQ7posEtlQEGet0QQEayxdMQ2se/U06xsvh3P5NjQvpUzI6+zsul2Wus3MjT+PuO5IXybZVnjzYxMxLFiibhNdCf307HgBqI1bcTcdm5c+m26R/fjKBfBTvYzU+wMm+bkQDaXYiKTJJ1JIlaTM0lWNt7GFc2fIuZ2MJB6l8M9L+JZD7GKkx/sYTDVRSY7Qcab4N8nf01qYpDB1HFOD7+OlhqyuVE8P4OIomvwFTw/O9nHTJnIJMnmUlNtqnoIAbChfQurlrVj
)
My xmlHandler code is below
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
import com.bvbi.invoicing.client.android.customer.model.CustomerPojoInList;
public class CustomerListParser extends DefaultHandler {
Boolean currentElement = false;
String tempValue = null;
CustomerPojoInList customer = null;
public static ArrayList<CustomerPojoInList> customers = null;
#Override
public void startDocument() throws SAXException {
customers = new ArrayList<CustomerPojoInList>();
}
/** Called when tag starts ( ex:- <name>AndroidPeople</name>
* -- <name> )*/
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentElement = true;
if (localName.equals("Customer"))
{
/** Start */
customer = new CustomerPojoInList();
}
}
/** Called when tag closing */
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
String currentValue = tempValue;
tempValue = "";
/** set value */
if (localName.equalsIgnoreCase("customerId"))
customer.setCustomerId(currentValue.toString());
else if (localName.equalsIgnoreCase("customerFname"))
customer.setCustomerFname(currentValue.toString());
else if (localName.equalsIgnoreCase("customerLname"))
customer.setCustomerLname(currentValue.toString());
else if (localName.equalsIgnoreCase("customerImage"))
{
Log.d("prabhu","Customer image in parser......"+currentValue);
customer.setCustomerImage(currentValue.toString());
}
else if (localName.equalsIgnoreCase("Customer"))
customers.add(customer);
}
/** Called to get tag characters */
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (currentElement) {
tempValue = new String(ch,start, length);
if(tempValue.equals(null))
tempValue = "";
currentElement = false;
}
}
#Override
public void endDocument() throws SAXException {
}
}
Please help me to fix the issue.
In sax parser, characters() method parses only maximum of 1024 characters each time. So we need to append the strings until all the characters are parsed.
I changed the above code as follows
public void characters(char[] ch, int start, int length)
throws SAXException
{
Log.d("prabhu","Customer image length in parser......"+length);
if (currentElement ) {
tempValue = new String(ch,start, length);
if(tempValue.equals(null))
tempValue = "";
}
tempValue = tempValue+new String(ch,start, length);
}
The output you posted is exactly 1024 characters. This looks like a certain buffer size. How do you get this output? Maybe check that method and / or your CustomerPojoInList.
I very much believe, that there is some buffer involved that has a maximum of 1024 characters...
Good luck!
first time post. Updated answer with something that might help others. I hope it is not too specific to my particular problem. I am parsing an RSS feed that I create myself with a really long description but the other tags you are interested in, i.e. feed title, date and URL are always short. The description contains information about social events. Within the description, I use tags that I later parse to give me information about the event such as event date (different from RSS pubDate), (Location), (ticketDetails), (Phone), etc, you get the idea.
A good way to handle this is with a slight modification of the answer in this post. I added tags to the description for (Event) and (EndEvent) and I keep appending to my String Builder until I get "(EndEvent)". That way i know i have the full string. It might not work for your situation if you dont control the feed unless you know there is always a certain string at the end of your RSS description.
Posting in case this (cough, hack) helps anyone. Code is as follows:
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
strBuilder = new StringBuilder();
if ("item".equals(qName)) {
currentItem = new RssItem();
} else if ("title".equals(qName)) {
parsingTitle = true;
} else if ("link".equals(qName)) {
parsingLink = true;
}
else if ("pubDate".equals(qName)) {
parsingDate = true;
}
else if ("description".equals(qName)) {
strBuilder = new StringBuilder(); //reset the strBuilder variable to null
parsingDescription = true;
}
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
String descriptionTester = strBuilder.toString();
if ("item".equals(qName)) {
rssItems.add(currentItem);
currentItem = null;
} else if ("title".equals(qName)) {
parsingTitle = false;
} else if ("link".equals(qName)) {
parsingLink = false;
}
else if ("pubDate".equals(qName)) {
parsingDate = false;
}
//else
// currentItem.setDescription(descriptionTester);
else if ("description".equals(qName) && descriptionTester.contains("(EndEvent)")) {
parsingDescription = false;
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (strBuilder != null) {
for (int i=start; i<start+length; i++) {
strBuilder.append(ch[i]);
}
}
if (parsingTitle) {
if (currentItem != null)
currentItem.setTitle(new String(ch, start, length));
parsingTitle = false;
}
else if (parsingLink) {
if (currentItem != null) {
currentItem.setLink(new String(ch, start, length));
parsingLink = false;
}
}
else if (parsingDate) {
if (currentItem != null) {
currentItem.setDate(new String(ch, start, length));
parsingDate = false;
}
}
else if (parsingDescription) {
if (currentItem != null && strBuilder.toString().contains("(EndEvent)" )) {
String descriptionTester = strBuilder.toString();
currentItem.setDescription(descriptionTester);
parsingDescription = false;
}
}
}
As I said, hope that helps someone as I was stumped on this for a while!
When I parse following XML and store it in HashMap the message is cut after (') this symbol.
Ex. Message: "Hey amar! What's up?". it cut like this.
message =(3577): Hey amar! What
message =(3577): '
message =(3577): s up?
The final out put is : message = "s up?"
So how to solve this problem ?
HashMap's for Shoring XML DATA :
public static HashMap<String,String> message_map1 = new HashMap<String,String>();
public static HashMap<String,String> message_map2 = new HashMap<String,String>();
public static HashMap<String,String> message_map3 = new HashMap<String,String>();
XML:
<statuses type="array">
<status>
<messageinfo>
<messageid>485</messageid>
<userid>58</userid>
**<message>Hey amar! What's up?</message>**
</messageinfo>
<messageinfo>
<messageid>486</messageid>
<userid>58</userid>
**<message>Hey What's up?</message>**
</messageinfo>
<messageinfo>
<messageid>485</messageid>
<userid>58</userid>
**<message>What's up?</message>**
</messageinfo>
</status>
</statuses>
code:
package com.xmldataparser;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Log;
public class Message_XHandler extends DefaultHandler
{
boolean in_porf_msg_statuses;
boolean in_prof_msg_status;
boolean in_prof_msg_messageinfo;
boolean in_prof_msg_messageid;
boolean in_prof_msg_userid;
boolean in_prof_msg_message;
int i=0;
public String key = "";
public String value = "";
XMLData xml_message;
#Override
public void startDocument() throws SAXException
{
super.startDocument();
xml_message = new XMLData();
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
super.startElement(uri, localName, qName, attributes);
if(localName.equalsIgnoreCase("statuses"))
{
in_porf_msg_statuses= true;
}
else if(localName.equalsIgnoreCase("status"))
{
in_prof_msg_status = true;
}
else if(localName.equalsIgnoreCase("messageinfo"))
{
in_prof_msg_messageinfo = true;
i++;
}
else if(localName.equalsIgnoreCase("messageid"))
{
in_prof_msg_messageid = true;
}
else if(localName.equalsIgnoreCase("userid"))
{
in_prof_msg_userid = true;
}
else if(localName.equalsIgnoreCase("message"))
{
in_prof_msg_message = true;
}
}
#Override
public void characters(char[] ch, int start, int length)
throws SAXException
{
super.characters(ch, start, length);
String chars = new String(ch,start,length);
chars = chars.trim();
else if(in_prof_msg_messageid)
{
if(i==1)
{
xml_message.message_map1.put("messageid", chars);
}
else if(i==2)
{
xml_message.message_map2.put("messageid", chars);
}
else if(i==3)
{
xml_message.message_map3.put("messageid", chars);
}
Log.v("messageid = ", chars);
}
else if(in_prof_msg_userid)
{
if(i==1)
{
xml_message.message_map1.put("userid", chars);
}
else if(i==2)
{
xml_message.message_map2.put("userid", chars);
}
else if(i==3)
{
xml_message.message_map3.put("userid", chars);
}
Log.v("userid = ", chars);
}
else if(in_prof_msg_message)
{
if(i==1)
{
xml_message.message_map1.put("message", chars);
}
else if(i==2)
{
xml_message.message_map2.put("message", chars);
}
else if(i==3)
{
xml_message.message_map3.put("message", chars);
}
Log.v("message = ", chars);
}
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException
{
super.endElement(uri, localName, qName);
if(localName.equalsIgnoreCase("statuses"))
{
in_porf_msg_statuses = false;
}
else if(localName.equalsIgnoreCase("messageinfo"))
{
in_prof_msg_messageinfo = false;
}
else if(localName.equalsIgnoreCase("messageid"))
{
in_prof_msg_messageid = false;
}
else if(localName.equalsIgnoreCase("userid"))
{
in_prof_msg_userid= false;
}
else if(localName.equalsIgnoreCase("message"))
{
in_prof_msg_message = false;
}
}
#Override
public void endDocument() throws SAXException
{
super.endDocument();
}
public XMLData getProfileMessageData()
{
Log.v("WHERE","Message_XHandler getProfileMessageData()");
return xml_message;
}
}
Problem :
Log:
07-04 13:38:37.924: VERBOSE/message =(3577): Hey amar! What
07-04 13:38:37.934: VERBOSE/message =(3577): '
07-04 13:38:37.934: VERBOSE/message =(3577): s up?
The characters method can be called multiple times by the parser, supplying only part of the characters inside a given tag on each call.
This code does not allow for that happening.
What you have to do is setup a string buffer in the startElement method, collect characters into it in the characters and extract the string result in the endElement method.
As Don Roby Answered..
Take a String variable and add in your map at endElement() method where your in_message variable goes false.
For Example do this...
String str = "";
//In characters() Method
else if(in_message)
{
str += chars;
}
//In endElement() Method
else if(localName.equalsIgnoreCase("message"))
{
in_message = false;
map.put("message", str);
Log.i("map "+i," message = "+str);
str = "";
}
`
EveryOne I am doing xml parsing like This
public class XMLHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
static ArrayList<Category1> cat_list=new ArrayList<Category1>();
static ArrayList<Products> product_list=new ArrayList<Products>();
Category1 cat;
Products pro;
private boolean in_outertag = false;
private boolean in_innertag = false;
private boolean in_mytag = false;
private boolean in_mytag1 = false;
private boolean in_mytag2 = false;
private boolean in_mytag3 = false;
private XMLDataSet myParsedExampleDataSet = new XMLDataSet();
// ===========================================================
// Getter & Setter
// ===========================================================
public XMLDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
// ===========================================================
// Methods
// ===========================================================
#Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new XMLDataSet();
}
#Override
public void endDocument() throws SAXException {
// Nothing to do
}
/** Gets be called on opening tags like:
* <tag>
* Can provide attribute(s), when xml was like:
* <tag attribute="attributeValue">*/
#Override
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) throws SAXException {
if (localName.equals("root")) {
this.in_outertag = true;
}else if (localName.equals("Categories")) {
this.in_innertag = true;
}else if (localName.equals("Category")) {
cat =new Category1();
String attrValue = atts.getValue("id");
int i = Integer.parseInt(attrValue);
myParsedExampleDataSet.setExtractedInt(i);
cat.setCatId(i+"");
//cat_id[i]=myParsedExampleDataSet.setExtractedInt(i);
//Log.i("id", cat.setCatId(i+""));
String attrValue1 = atts.getValue("pid");
int i1 = Integer.parseInt(attrValue1);
myParsedExampleDataSet.setExtractedInt(i1);
cat.setPid(i1+"");
//p_id[i1]=myParsedExampleDataSet.setExtractedInt(i1);
//Log.i("pid", myParsedExampleDataSet.setExtractedInt(i1)+"");
this.in_mytag = true;
}else if (localName.equals("title")) {
// Extract an Attribute
this.in_mytag1 = true;
}else if (localName.equals("products")) {
this.in_innertag = true;
}else if (localName.equals("product")) {
pro=new Products();
String attrValue = atts.getValue("catid");
int i = Integer.parseInt(attrValue);
myParsedExampleDataSet.setExtractedInt(i);
pro.setCatId(i+"");
//Log.i("catid", myParsedExampleDataSet.setExtractedInt(i)+"");
this.in_mytag = true;
}else if (localName.equals("name")) {
// Extract an Attribute
this.in_mytag2 = true;
}else if (localName.equalsIgnoreCase("url")) {
// Extract an Attribute
this.in_mytag3 = true;
}
}
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("root")) {
this.in_outertag = false;
}else if (localName.equals("Categories")) {
this.in_innertag = false;
}else if (localName.equals("Category")) {
cat_list.add(cat);
this.in_mytag = false;
}else if (localName.equals("title")) {
this.in_mytag1=false;
}else if (localName.equals("products")) {
this.in_innertag=false;
}else if (localName.equals("product")) {
product_list.add(pro);
this.in_mytag=false;
}else if (localName.equals("name")) {
this.in_mytag2=false;
}else if (localName.equalsIgnoreCase("url")) {
this.in_mytag3=false;
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(this.in_mytag1){
myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
cat.setCatName(new String(ch, start, length));
}
if(this.in_mytag2){
myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
pro.setProductId(new String(ch, start, length));
}
if(this.in_mytag3){
String chars = new String(ch, start, length);
chars = chars.trim();
//myParsedExampleDataSet.setExtractedString(chars);
pro.setUrl(chars);
}
}
}
I parse all thing very good but not url....
The Xml file is like this
<?xml version="1.0" encoding="UTF-16"?>
<products>
<product catid="11">
<name>song1</name>
<url>http://news.google.co.in/news?edchanged=1&ned=en_il</url>
</product>
I got the result ned=en_il only
Please Help me, Where i am wrong??
Thankx
You may try by warping your <url> node into CDATA tag like this
<url><![CDATA[http://news.google.co.in/news?edchanged=1&ned=en_il]]></url>
to rectify the issue.
I would recommend using android.sax for parsing it is much easier. You can read about it here http://www.ibm.com/developerworks/opensource/library/x-android/
The problem is likely to be in your characters method.
This method may be called several times for a given element, your code is assuming it will only be called once. e.g. It is likely called for "http://news.google.co.in", "/news?edchanged=1&" and "ned=en_il"
If you append the characters to appropriate properties instead of setting them it will probably work.