SAX Parser will not read and print one section of my xml File
I really need someone help in trying to get my parser to read and show just one section of xml file, i can get it two read from top to bottom but when i try and use the inner tags in my xml handler that separate each section out it doesn't do it and goes mental and shows one bit of it
This is the code for my Parser
package heavytime
import java.net.URL;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
//import android.content.Intent;
import android.os.Bundle;
//import android.view.View;
//import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class Mainweather extends Seskanoreweatherpart2Activity {
weatherlist sitesList = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
layout.setBackgroundColor(0xFF000080);
TextView value [];
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://www.seskanore.com/currentoutput.xml");
/** Create handler to handle XML Tags ( extend开发者_StackOverflow中文版s DefaultHandler ) */
XMLhandler XMLhandler = new XMLhandler();
xr.setContentHandler(XMLhandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
/** Get result from XMLhandler SitlesList Object */
sitesList = XMLhandler.sitesList;
/** Assign textview array lenght by arraylist size */
// item = new TextView[sitesList.getName().size()];
value = new TextView[sitesList.getName().size()];
/** Set the result text in textview and add it to layout */
for (int i = 0; i < sitesList.getName().size(); i++) {
value[i] = new TextView(this);
value[i].setText(sitesList.getvalue().get(i)+ " is " +sitesList.getitem().get(i));
layout.addView(value[i]);
}
/** Set the layout view to display */
setContentView(layout);
}
}
This is the code for my XML handler
package heavytime
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class XMLhandler extends DefaultHandler {
Boolean currentElement = false;
Boolean temperature = false;
String currentValue = null;
// int currentVal = 0;
public static weatherlist sitesList = null;
public static weatherlist getSitesList() {
return sitesList;
}
public static void setSitesList(weatherlist sitesList) {
XMLhandler.sitesList = sitesList;
}
@Override
public void startDocument() throws SAXException {
// Some sort of setting up work
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentElement = true;
if (localName.equals("weatherdata"))
{
sitesList = new weatherlist();}
else if (localName.equals("item")){
temperature = true;
String attr = attributes.getValue("name");
sitesList.setValue(attr);}
}
/** Called when tag closing*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
/** set value*/
if (localName.equals("temperaturetags")){
localName.equalsIgnoreCase("item");
sitesList.setName(currentValue);
localName.equalsIgnoreCase("value");
sitesList.setitem(currentValue);
}
temperature = false;
}
/** 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;
}
}
@Override
public void endDocument() throws SAXException {
// Some sort of finishing up work
}
}
This the Code for my Arraylist for displaying the parsed information
package heavytime
import java.util.ArrayList;
public class weatherlist {
private ArrayList<String> value = new ArrayList<String>();
private ArrayList<String> name = new ArrayList<String>();
private ArrayList<String> item = new ArrayList<String>();
/** In Setter method default it will return arraylist
* change that to add */
public ArrayList<String> getvalue() {
return value;
}
public void setValue(String value) {
this.value.add(value);
}
public ArrayList<String> getName() {
return name;
}
public void setName(String name) {
this.name.add(name);
}
public ArrayList<String> getitem() {
return item;
}
public void setitem(String item) {
this.item.add(item);
}
}
I want it to display just the tags within the temperature tags but ive tried everything and nothing seems to work Can someone please help me
Much appreciated
You're making the common mistake of assuming that the characters
method will be called only once between a pair of startElement
and endElement
calls from the parser and supply the entore content between the start and end tags. It can actually be called many times, and each call contains only part of the content.
The proper handling is to create or attach an accumulator of some sort (commonly a StringBuilder
or StringBuffer
) in the startElement method, accumulate into it in the characters method, and then to use and dispose or detach it in the endElement method.
I think there's a good bit more wrong in your code, but this may be a start toward getting it working.
In order to process only the items within a particular tag, you'll want to set a boolean flag connoting that you've found it in the startElement
method on seeing that tag, set it false in the endElement for the tag, and test that flag before collecting data from any other tags. You'll need to use the process described above for each of the subtags withing <item>
, as they contain their data as characters.
For my own amusement, and in hopes that it might help you understand all this a bit better, I've written a little handler that collects the data under <temperaturetags>
into a list of maps.
package com.donroby;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WeatherHandler extends DefaultHandler {
private List<Map<String,String>> result = new ArrayList<Map<String,String>>();
private Map<String,String> currentItem;
private boolean collectingItems;
private boolean collectingItem;
private StringBuilder builder;
public List<Map<String,String>> getResult() {
return result;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("temperaturetags")) {
collectingItems = true;
}
else if (qName.equals("item") && collectingItems) {
currentItem = new HashMap<String,String>();
currentItem.put("name", attributes.getValue("name"));
collectingItem = true;
}
else if (collectingItem) {
builder = new StringBuilder();
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("temperaturetags")) {
collectingItems = false;
}
if (qName.equals("item") && collectingItems) {
result.add(currentItem);
currentItem = null;
collectingItem = false;
}
else if (collectingItem) {
currentItem.put(qName, builder.toString());
builder = null;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (collectingItem &&(builder != null)) {
builder.append(ch, start, length);
}
}
}
For real use, I would more likely create a domain object and collect into a list of that class, but that would bloat the code a bit beyond what I wanted to do for a quick sample.
In characters()
function, use String.trim()
and then check if String.length()>0
before proceeding.
Then use a stack
model and push()
and pop()
data at startElement()
and endElement()
events respectively
精彩评论