I have this string coming from my dataBase:
<user>
<name>John</name>
<surname>Shean</surname>
<birthdate>1/1/1111</birthdate>
<phone >(555) 444-1111</phone>
<city>NY</city>
</user>
I need to parse it and add to:
arrayList<User>.(User(name,surname,...))
It should end up looking like this:
user[1]={name="John",surname="Shena",...}
I used the following method but it isn't working right. Does anyone have a method to will do this?
public User parseList(String array) {
User user = new User();
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
URL u = new URL("xmldb:exist://192.168.1.71:8094/exist/xmlrpc/db/testDB/userInformation.xml");
Document doc = builder.parse(u.openStream());
NodeList nodes = doc.getElementsByTagName("user");
Element element = (Element) nodes.item(0);
user.setName(getElementValue(element, "name"));
user.setSurname(getElementValue(element, "surname"));
user.setBirthdate(getElementValue(element, "birthdate"));
user.setPhone(getElementValue(element, "phone"));
user.setCity(getElementValue(element, "city"));
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
protected String getElementValue(Element parent, String label) {
return getCharacterDataFromElement((Element) parent.getElementsByTagName(label).item(0));
}
private String getCharacterDataFromElement(Element e) {
try {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
} catch (Exception ex) {
}
return "";
}
1 - model your use class:
package com.howtodoinjava.xml.sax;
/**
* Model class. Its instances will be populated using SAX parser.
* */
public class User
{
//XML attribute id
private int id;
//XML element name
private String Name;
//XML element surname
private String SurName;
//...
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public String getSurName() {
return SurName;
}
public void setSurName(String SurName) {
this.SurName = SurName;
}
// [...]
#Override
public String toString() {
return this.id + ":" + this.Name + ":" +this.SurName ;
}
}
2 - Build the handler by extending DefaultParser
package com.howtodoinjava.xml.sax;
import java.util.ArrayList;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class UserParserHandler extends DefaultHandler
{
//This is the list which shall be populated while parsing the XML.
private ArrayList userList = new ArrayList();
//As we read any XML element we will push that in this stack
private Stack elementStack = new Stack();
//As we complete one user block in XML, we will push the User instance in userList
private Stack objectStack = new Stack();
public void startDocument() throws SAXException
{
//System.out.println("start of the document : ");
}
public void endDocument() throws SAXException
{
//System.out.println("end of the document document : ");
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
//Push it in element stack
this.elementStack.push(qName);
//If this is start of 'user' element then prepare a new User instance and push it in object stack
if ("user".equals(qName))
{
//New User instance
User user = new User();
//Set all required attributes in any XML element here itself
if(attributes != null && attributes.getLength() == 1)
{
user.setId(Integer.parseInt(attributes.getValue(0)));
}
this.objectStack.push(user);
}
}
public void endElement(String uri, String localName, String qName) throws SAXException
{
//Remove last added element
this.elementStack.pop();
//User instance has been constructed so pop it from object stack and push in userList
if ("user".equals(qName))
{
User object = this.objectStack.pop();
this.userList.add(object);
}
}
/**
* This will be called everytime parser encounter a value node
* */
public void characters(char[] ch, int start, int length) throws SAXException
{
String value = new String(ch, start, length).trim();
if (value.length() == 0)
{
return; // ignore white space
}
//handle the value based on to which element it belongs
if ("name".equals(currentElement()))
{
User user = (User) this.objectStack.peek();
user.setName(value);
}
else if ("surname".equals(currentElement()))
{
User user = (User) this.objectStack.peek();
user.setSurName(value);
}
}
/**
* Utility method for getting the current element in processing
* */
private String currentElement()
{
return this.elementStack.peek();
}
//Accessor for userList object
public ArrayList getUsers()
{
return userList;
}
}
3 - Write parser for xml file
package com.howtodoinjava.xml.sax;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
public class UsersXmlParser
{
public ArrayList parseXml(InputStream in)
{
//Create a empty link of users initially
ArrayList<user> users = new ArrayList</user><user>();
try
{
//Create default handler instance
UserParserHandler handler = new UserParserHandler();
//Create parser from factory
XMLReader parser = XMLReaderFactory.createXMLReader();
//Register handler with parser
parser.setContentHandler(handler);
//Create an input source from the XML input stream
InputSource source = new InputSource(in);
//parse the document
parser.parse(source);
//populate the parsed users list in above created empty list; You can return from here also.
users = handler.getUsers();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
}
return users;
}
}
4 - Test parser
package com.howtodoinjava.xml.sax;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
public class TestSaxParser
{
public static void main(String[] args) throws FileNotFoundException
{
//Locate the file OR String
File xmlFile = new File("D:/temp/sample.xml");
//Create the parser instance
UsersXmlParser parser = new UsersXmlParser();
//Parse the file Or change to parse String
ArrayList users = parser.parseXml(new FileInputStream(xmlFile));
//Verify the result
System.out.println(users);
}
}
If you want to parse XML, you can use an XML parser.
This may help you:
Java:XML Parser
Related
I need to parse the XML string into Object. Please find the class and XML string details below
Country class
public class Country {
private String Country_Name;
private String Country_Capital;
private String Country_Foundation_Date;
private String Country_Continent;
private String Country_Population;
public String getCountry_Name() {
return Country_Name;
}
public void setCountry_Name(String country_Name) {
Country_Name = country_Name;
}
public String getCountry_Capital() {
return Country_Capital;
}
public void setCountry_Capital(String country_Capital) {
Country_Capital = country_Capital;
}
public String getCountry_Foundation_Date() {
return Country_Foundation_Date;
}
public void setCountry_Foundation_Date(String country_Foundation_Date) {
Country_Foundation_Date = country_Foundation_Date;
}
public String getCountry_Continent() {
return Country_Continent;
}
public void setCountry_Continent(String country_Continent) {
Country_Continent = country_Continent;
}
public String getCountry_Population() {
return Country_Population;
}
public void setCountry_Population(String country_Population) {
Country_Population = country_Population;
}
}
Parse Code Implementation
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
public class ParseXMLStringtoObject {
public static String getXMLString() {
StringBuilder returnString = new StringBuilder();
returnString.append("<output xmlprop = \"somevalue\"> ");
returnString.append("<Country> ");
returnString.append("<Country_Name equals=\"Spain\" type=\"1\" /> ");
returnString.append("<Country_Capital equals = \"Madrid\" type=\"1\" /> ");
returnString.append("<Country_Foundation_Date equals=\"1469-10-19\" type=\"3\" /> ");
returnString.append("<Country_Continent equals=\"Europe\" type = \"1\" /> ");
returnString.append("<Country_Population equals=\"45\" type = \"2\" /> ");
returnString.append("</Country> ");
return returnString.toString();
}
public static Object getObjectFromStringXml(Class<Country> country)
throws IllegalAccessException, InstantiationException {
Object obj = getObject(country.newInstance());
try {
StringReader reader = new StringReader(getXMLString());
JAXBContext context = JAXBContext.newInstance(country);
Unmarshaller jaxbUnmarshaller = context.createUnmarshaller();
JAXBElement<?> root = jaxbUnmarshaller.unmarshal(new StreamSource(reader), country);
obj = root.getValue();
} catch (Exception e) {
System.out.printf("Exception occoured while unmarshalling xml String to " + obj.getClass() +" Object", e);
}
return obj;
}
private static Object getObject(Object obj) {
if (obj instanceof Country) {
obj = (Country) obj;
}
return obj;
}
public static void main(String[] args) {
Country country = new Country();
//Class<Country> countryObj = new Class<Country>(); // I don't know how to convert my Country object
//or don't know the input value to the getObjectFromStringXml method
ParseXMLStringtoObject parseXML = new ParseXMLStringtoObject();
try{
//This is the place I have the doubt to call the parse method, regarding input
Object obj = parseXML.getObjectFromStringXml(Class<Country> countryObj);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Where type attribute indicates the type of the values present in equals attribute. For example 1 indicates String, 2 indicates int and 3 indicates list.
Can anyone let me know the solution to map the above xml string into Java Object.
You can try unmarshalling to java object using JAXB something like below:
public static Object getObjectFromStringXml(String xml, Class<Country> country)
throws IllegalAccessException, InstantiationException {
Object obj = getObject(country.newInstance());
try {
StringReader reader = new StringReader(xml);
JAXBContext context = JAXBContext.newInstance(country);
Unmarshaller jaxbUnmarshaller = context.createUnmarshaller();
JAXBElement<?> root = jaxbUnmarshaller.unmarshal(new StreamSource(
reader), country);
obj = root.getValue();
} catch (Exception e) {
log.info("Exception occoured while unmarshalling xml String to " + obj.getClass() +" Object", e);
}
return obj;
}
private static Object getObject(Object obj) {
if (obj instanceof Country) {
obj = (Country) obj;
}
return obj;
}
My implemented SAXParser class which uses URL address to process XML data does not returns the result. The class uses additional Currency class which in turn stores two variables currId and rate with setters/getters. When I run my class nothing shows up in java console. Here is the code:
public class MySAXParser extends DefaultHandler {
private static List<Currencies> currencies = new ArrayList<Currencies>();
private static Currencies curr = null;
private static String text = null;
public static void main(String[] args) {
String url = "http://nbt.tj/en/kurs/export_xml.php?date=2016-08-01&export=xmlout";
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
MySAXParser handler = new MySAXParser();
URL uri = new URL(url);
sp.parse(new InputSource(uri.openStream()), handler);
} catch (Exception ex) {
ex.printStackTrace();
}
for (Currencies curr : currencies) {
System.out.println(curr.toString());
}
}
public void startElement (String s, String s1, String elementName, Attributes atts) throws SAXException {
if (elementName.equalsIgnoreCase("valute")) {
curr = new Currencies();
curr.setCurrId(atts.getValue("id"));
}
}
public void endElement (String s, String s1, String element) throws SAXException {
if (element.equals("valute")) {
currencies.add(curr);
}
if (element.equalsIgnoreCase("value")) {
curr.setRate(Double.parseDouble(text));
}
}
#Override
public void characters (char[] ch, int start, int length) throws SAXException {
text = String.copyValueOf(ch, start, length).trim();
}
}
So, what I missed or doing wrong? Any help would be appreciated.
Here is my attempt that works fine with Java 1.8:
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MySAXParser extends DefaultHandler {
private List<Currency> currencies = new ArrayList<>();
private Currency curr = null;
private StringBuilder sb;
public static void main(String[] args) {
String url = "http://nbt.tj/en/kurs/export_xml.php?date=2016-08-01&export=xmlout";
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
SAXParser sp = spf.newSAXParser();
MySAXParser handler = new MySAXParser();
sp.parse(new InputSource(url), handler);
for (Currency curr : handler.getCurrencies()) {
System.out.println(curr.toString());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public List<Currency> getCurrencies() {
return currencies;
}
#Override
public void startElement(String s, String localName, String elementName, Attributes atts) throws SAXException {
if (elementName.equalsIgnoreCase("valute")) {
curr = new Currency();
currencies.add(curr);
curr.setCurrId(atts.getValue("ID"));
} else if (elementName.equalsIgnoreCase("value") || elementName.equalsIgnoreCase("CharCode")) {
sb = new StringBuilder();
}
}
#Override
public void endElement(String s, String localName, String elementName) throws SAXException {
if (elementName.equalsIgnoreCase("value")) {
curr.setRate(Double.parseDouble(sb.toString()));
sb = null;
}
else if (elementName.equalsIgnoreCase("CharCode")) {
curr.setCharCode(sb.toString());
sb = null;
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (sb != null) {
sb.append(ch, start, length);
}
}
}
The class is
public class Currency {
private String currId;
/**
* Get the value of currId
*
* #return the value of currId
*/
public String getCurrId() {
return currId;
}
/**
* Set the value of currId
*
* #param currId new value of currId
*/
public void setCurrId(String currId) {
this.currId = currId;
}
private double rate;
/**
* Get the value of rate
*
* #return the value of rate
*/
public double getRate() {
return rate;
}
/**
* Set the value of rate
*
* #param rate new value of rate
*/
public void setRate(double rate) {
this.rate = rate;
}
private String charCode;
/**
* Get the value of charCode
*
* #return the value of charCode
*/
public String getCharCode() {
return charCode;
}
/**
* Set the value of charCode
*
* #param charCode new value of charCode
*/
public void setCharCode(String charCode) {
this.charCode = charCode;
}
#Override
public String toString() {
return "Currency{" + "currId=" + currId + ", rate=" + rate + ", charCode=" + charCode + '}';
}
}
A sample output I get is
Currency{currId=840, rate=7.8683, charCode=USD}
Currency{currId=978, rate=8.7448, charCode=EUR}
Currency{currId=960, rate=10.9395, charCode=XDR}
Currency{currId=156, rate=1.1828, charCode=CNY}
Currency{currId=756, rate=8.075, charCode=CHF}
Currency{currId=810, rate=0.1146, charCode=RUB}
Currency{currId=860, rate=0.2655, charCode=UZS}
Currency{currId=417, rate=1.1643, charCode=KGS}
Currency{currId=398, rate=0.2234, charCode=KZT}
Currency{currId=933, rate=3.9424, charCode=BYR}
Currency{currId=364, rate=0.2617, charCode=IRR}
Currency{currId=971, rate=1.139, charCode=AFN}
Currency{currId=586, rate=0.7504, charCode=PKR}
Currency{currId=949, rate=2.6076, charCode=TRY}
Currency{currId=934, rate=2.2481, charCode=TMT}
Currency{currId=826, rate=10.3618, charCode=GBP}
Currency{currId=36, rate=5.9162, charCode=AUD}
Currency{currId=208, rate=1.1755, charCode=DKK}
Currency{currId=352, rate=0.659, charCode=ISK}
Currency{currId=124, rate=5.9699, charCode=CAD}
Currency{currId=414, rate=26.004, charCode=KWD}
Currency{currId=578, rate=0.9193, charCode=NOK}
Currency{currId=702, rate=5.8215, charCode=SGD}
Currency{currId=752, rate=0.9136, charCode=SEK}
Currency{currId=392, rate=0.761, charCode=JPY}
Currency{currId=944, rate=4.9639, charCode=AZN}
Currency{currId=51, rate=1.6516, charCode=AMD}
Currency{currId=981, rate=3.3539, charCode=GEL}
Currency{currId=498, rate=0.3979, charCode=MDL}
Currency{currId=980, rate=0.317, charCode=UAH}
Currency{currId=784, rate=2.1421, charCode=AED}
Currency{currId=682, rate=2.0979, charCode=SAR}
Currency{currId=356, rate=1.175, charCode=INR}
Currency{currId=985, rate=2.0039, charCode=PLN}
Currency{currId=458, rate=1.9313, charCode=MYR}
Currency{currId=764, rate=0.2258, charCode=THB}
I am trying to write a java program that reads in an XML file and returns various elements of interest to the user. I am having some issues getting it to compile and I have created a test class in order for it to be displayed properly. This is what I have thus far.
EDIT: The Bolded Line in the test class is giving me problems. The error is cannot convert from String to Resources.
public class T_Resources {
public static void main(String[] args) {
Resources resources = ResourceImporter.importResourcesFromXML("http://free1.ed.gov/xml/gemexport.xml");
displayResources(resources);
}
private static void displayResources(Resources resources) {
Subject[] subjects;
**Resources resource = resources.getTitle();**
System.out.println(resource.getTitle());
System.out.println(resource.getDescription());
System.out.println(resource.getIdentifier());
subjects = resource.getSubjects();
for (int i=0; i < subjects.length; ++i) {
System.out.println(subjects[i].getCategory() + " :: " + subjects[i].getSubcategory());
}
System.out.println();
}
}
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ResourceImporter {
// This operation loads the XML document specified by the document location, which can a file or a URL,
// and returns a reference to the document. If the operation cannot successfully load the document
// the operation returns the null reference.
//
private static Document loadXMLDocument(String documentLocation) {
// The XML document.
//
Document documentIn = null;
// The parser that reads in an XML files.
//
DocumentBuilder parser = null;
// Pull the document
//
try {
// Obtain a document parser.
//
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
parser = builderFactory.newDocumentBuilder();
documentIn = parser.parse(documentLocation);
} catch (ParserConfigurationException p) {
System.out.println("Error creating parser.");
System.out.println(" " + p.getMessage());
} catch (SAXException s) {
System.out.println("Document is not well formed.");
System.out.println(" " + s.getMessage());
} catch (IOException i) {
System.out.println("Error accessing the file.");
System.out.println(" " + i.getMessage());
} catch (Exception e) {
System.out.println("Unknown error occurred.");
System.out.println(" " + e.getMessage());
}
return documentIn;
}
public static Resources importResourcesFromXML(String documentLocation) {
Resources resource = new Resources();
Document doc;
Element resourceElement;
Element titleElement;
String title;
Element descriptionElement;
String description;
Element identifierElement;
String identifiers;
Element urlElement;
String url;
NodeList subjectList;
Element subjectElement;
String subjects;
Element categoryElement;
String category;
Element subcategoryElement;
String subcategory;
doc = loadXMLDocument(documentLocation);
resourceElement = (Element)doc.getElementsByTagName("resource").item(0);
if (resourceElement != null) {
titleElement = (Element)resourceElement.getElementsByTagName("title").item(0);
resource.setTitle( titleElement == null ? "unknown" : titleElement.getTextContent() );
descriptionElement = (Element)resourceElement.getElementsByTagName("description").item(0);
resource.setDescription( descriptionElement == null ? "unknown" : descriptionElement.getTextContent() );
identifierElement = (Element)resourceElement.getElementsByTagName("identifier").item(0);
if (identifierElement != null) {
Identifier identifier = new Identifier();
urlElement = (Element)identifierElement.getElementsByTagName("url").item(0);
identifier.setURL( urlElement == null ? "unknown" : urlElement.getTextContent() );
subjectElement = (Element)resourceElement.getElementsByTagName("subjects").item(0);
if (subjectElement != null) {
subjectList = subjectElement.getElementsByTagName("subject");
for (int i=0; i < subjectList.getLength(); ++i) {
Subject subject = new Subject();
subjectElement = (Element)subjectList.item(i);
categoryElement = (Element)subjectElement.getElementsByTagName("category").item(0);
subject.setCategory( categoryElement == null ? "unknown" : categoryElement.getTextContent() );
subcategoryElement = (Element)subjectElement.getElementsByTagName("subcategory").item(0);
subject.setSubcategory( subcategoryElement == null ? "unknown" :subcategoryElement.getTextContent() );
resource.addSubject(subject);
}
}
}
}
return resource;
}
}
public class Resources {
private static final int MAX_SUBJECTS = 20;
private String title;
private String description;
private Identifier identifier;
private Subject[] subjects;
private int subjectCount;
public Resources() {
title = "unknown title";
description = "unknown description";
identifier = null;
subjects = new Subject[MAX_SUBJECTS];
subjectCount = 0;
}
public void setTitle(String newTitle) {
title = newTitle;
}
public String getTitle() {
return title;
}
public void setDescription(String newDescription) {
description = newDescription;
}
public String getDescription() {
return description;
}
public void setIdentifier(Identifier newIdentifier) {
identifier = newIdentifier;
}
public Identifier getIdentifier() {
return identifier;
}
public void addSubject(Subject newSubject) {
subjects[subjectCount++] = newSubject;
}
public Subject[] getSubjects() {
Subject[] result = new Subject[subjectCount];
System.arraycopy(subjects, 0, result, 0, subjectCount);
return result;
}
}
public class Subject {
private String category;
private String subcategory;
public Subject() {
String category = "unknown";
String subcategory = "unknown";
}
public Subject(Subject subject) {
category = subject.category;
subcategory = subject.subcategory;
}
public void setCategory(String newCategory) {
category = (newCategory == null) ? "unknown" : newCategory;
}
public String getCategory() {
return category;
}
public void setSubcategory(String newSubcategory) {
subcategory = newSubcategory;
}
public String getSubcategory() {
return subcategory;
}
}
public class Identifier {
private String url;
public Identifier() {
url = "unknown";
}
public void setURL(String newURL) {
url = newURL;
}
public String getURL() {
return url;
}
}
The error lies in here:
private static void displayResources(Resources resources) {
Subject[] subjects;
// DELETE THIS
// **Resources resource = resources.getTitle();**
// RENAME 'resource' to 'resources', or just change the method parameter above...
System.out.println(resources.getTitle());
//System.out.println(resource.getTitle());
System.out.println(resources.getDescription());
//System.out.println(resource.getDescription());
System.out.println(resources.getIdentifier());
//System.out.println(resource.getIdentifier());
....
You pass a Resources Object, and normally you would want to work directly with it?
Currently this just seems borked here, all the other code works, I tested and get fancy console outputs.
EDIT: (Answering a comment below this post.)
In ResourceImporter.java add line following the comment below:
if (resourceElement != null) {
titleElement = (Element)resourceElement.getElementsByTagName("title").item(0);
resource.setTitle( titleElement == null ? "unknown" : titleElement.getTextContent() );
descriptionElement = (Element)resourceElement.getElementsByTagName("description").item(0);
resource.setDescription( descriptionElement == null ? "unknown" : descriptionElement.getTextContent() );
identifierElement = (Element)resourceElement.getElementsByTagName("identifier").item(0);
if (identifierElement != null) {
Identifier identifier = new Identifier();
urlElement = (Element)identifierElement.getElementsByTagName("url").item(0);
identifier.setURL( urlElement == null ? "unknown" : urlElement.getTextContent() );
// ADDED THIS LINE HERE
resource.setIdentifier(identifier);
subjectElement = (Element)resourceElement.getElementsByTagName("subjects").item(0);
if (subjectElement != null) {
subjectList = subjectElement.getElementsByTagName("subject");
....
You may also want to use this line for your syso's in the helper method being used in the main method: System.out.println(resources.getIdentifier().getURL());, otherwise you will get uninterpretable information.
I'd change
private static void displayResources(Resources resources)
to
private static void displayResources(Resources resource)
(notice I removed the 's'), and remove your bold line.
As stated by JB Nizet, your method returns a String when you want the Resources that is passed to your static method.
The getTitle() method is declared as
public String getTitle()
But you're assigning its result to a variabe of type Resources:
Resources resource = resources.getTitle();
That obviously can't work, hence the error, which is quite self-explanatory:
cannot convert from String to Resources
You probably want
String title = resources.getTitle();
instead.
I'm having a problem with SAX XML parser.
It Does parse everything, except quotation marks (").
For example, if the text is hell"3o in a node, the result is hell.
Here are my codes:
XML Handler:
public class MyXMLHandler extends DefaultHandler {
Boolean currentElement = false;
String currentValue = null;
public static SitesList sitesList = null;
public static SitesList getSitesList() {
return sitesList;
}
public static void setSitesList(SitesList sitesList) {
MyXMLHandler.sitesList = sitesList;
}
/** 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("channel"))
{
/** Start */
sitesList = new SitesList();
} else if (localName.equals("item")) {
String attr=attributes.getValue("item");
sitesList.setItem(attr);
} else if (localName.equals("title")) {
/** Get attribute value */
String attr = attributes.getValue("title");
sitesList.setTitle(attr);
}
else if (localName.equals("link")) {
/** Get attribute value */
String attr = attributes.getValue("link");
sitesList.setLink(attr);
}
else if (localName.equals("description")) {
/** Get attribute value */
String attr = attributes.getValue("description");
sitesList.setDescription(attr);
}
else if (localName.equalsIgnoreCase("pubDate")) {
/** Get attribute value */
String attr = attributes.getValue("pubDate");
sitesList.setPubDate(attr);
}
}
/** Called when tag closing ( ex:- <name>AndroidPeople</name>
* -- </name> )*/
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
/** set value */
if (localName.equalsIgnoreCase("item"))
sitesList.setItem(currentValue);
else if (localName.equalsIgnoreCase("title"))
sitesList.setTitle(currentValue);
else if (localName.equalsIgnoreCase("link"))
sitesList.setLink(currentValue);
else if (localName.equalsIgnoreCase("description"))
sitesList.setDescription(currentValue);
else if (localName.equalsIgnoreCase("pubDate"))
sitesList.setPubDate(currentValue);
}
/** 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) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}
}
Getter and Setter:
import java.util.ArrayList;
/** Contains getter and setter method for variables */
public class SitesList {
/** Variables */
private ArrayList<String> title = new ArrayList<String>();
private ArrayList<String> link = new ArrayList<String>();
private ArrayList<String> description = new ArrayList<String>();
private ArrayList<String> pubDate = 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> getTitle() {
return title;
}
public void setTitle(String title) {
this.title.add(title);
}
public ArrayList<String> getLink() {
return link;
}
public void setLink(String link) {
this.link.add(link);
}
public ArrayList<String> getDescription() {
return description;
}
public void setDescription(String description) {
this.description.add(description);
}
public ArrayList<String> getPubDate() {
return this.pubDate;
}
public void setPubDate(String PubDate) {
this.pubDate.add(PubDate);
}
public ArrayList<String> getItem() {
return this.item;
}
public void setItem(String item) {
this.item.add(item);
}
}
And RSS Thread class:
public class RssThread {
private String title,html,pubDate;
public RssThread(String title,String html,String pubDate)
{
this.title=title;
this.html=html;
this.pubDate=CovertToDate(pubDate);
}
private String CovertToDate(String pubDate) {
// TODO Auto-generated method stub
//Wed, 28 Sep 2011 11:40:51//
String newDate="";
if (pubDate.substring(0,pubDate.indexOf(",")).equals("Sun"))
newDate+="יום ראשון";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Mon"))
newDate+="יום שני";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Tue"))
newDate+="יום שלישי";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Wed"))
newDate+="יום רביעי";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Thu"))
newDate+="יום חמישי";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Fri"))
newDate+="יום שישי";
else if (pubDate.subSequence(0, pubDate.indexOf(",")).equals("Sat"))
newDate+="יום שבת";
newDate+=", ";
String[] splited = pubDate.split(" ");
newDate += splited[1]+".";
if (splited[2].equals("Jan"))
newDate+="1.";
else if (splited[2].equals("Feb"))
newDate+="2.";
else if (splited[2].equals("Mar"))
newDate+="3.";
else if (splited[2].equals("Apr"))
newDate+="4.";
else if (splited[2].equals("May"))
newDate+="5.";
else if (splited[2].equals("Jun"))
newDate+="6.";
else if (splited[2].equals("Jul"))
newDate+="7.";
else if (splited[2].equals("Aug"))
newDate+="8.";
else if (splited[2].equals("Sep"))
newDate+="9.";
else if (splited[2].equals("Oct"))
newDate+="10.";
else if (splited[2].equals("Nov"))
newDate+="11.";
else if (splited[2].equals("Dec"))
newDate+="12.";
newDate+=splited[3];
newDate+=", בשעה "+splited[4].substring(0,splited[4].lastIndexOf(":"));
return newDate;
}
public String getTitle() {
return this.title;
}
public String getHTML() {
return html;
}
public String getPubDate() {
return this.pubDate;
}
}
I have forgotten to put another class:
public class XMLParsingExample {
private static String[] RssString;
/** Create Object For SiteList Class */
SitesList sitesList = null;
/** Called when the activity is first created. */
/** Create a new textview array to display the results */
String[] title;
String[] link;
String[] pubDate;
{
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.blich.co.il/rss.xml");
/** Create handler to handle XML Tags ( extends DefaultHandler ) */
MyXMLHandler myXMLHandler = new MyXMLHandler();
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
/** Get result from MyXMLHandler SitlesList Object */
sitesList = MyXMLHandler.sitesList;
/** Assign textview array lenght by arraylist size */
title = new String[sitesList.getTitle().size()];
link = new String[sitesList.getTitle().size()];
pubDate = new String[sitesList.getTitle().size()];
/** Set the result text in textview and add it to layout */
RssString=new String[sitesList.getItem().size()/2];
for (int i=0;i<RssString.length;i++)
RssString[i]="";
int counter=1;
for (int i = 0; i < sitesList.getItem().size(); i++) {
if (i%2!=0) {
title[i-counter]=sitesList.getTitle().get(i);
if (title[i-counter]!=null)
RssString[i-counter]+=title[i-counter]+"~";
link[i-counter]=sitesList.getLink().get(i);
if (link[i-counter]!=null)
RssString[i-counter]+=link[i-counter]+"~";
pubDate[i-counter]=sitesList.getPubDate().get(i);
if (pubDate[i-counter]!=null)
RssString[i-counter]+=pubDate[i-counter]+"~";
counter++;
}
}
}
public static String[] getRSSarray() {
return RssString;
}
}
I gave you all the codes so you can see everything.
the characters method can be called several times. try to look what you get in there and try to accumulate values in a stringbuffer
You can create an HTML object that will convert the HTML codes to the appropriate symbol (i.e. " to "), then convert that back to a String (or a SpannedString if you want to format it)
CharSequence seq = Html.fromHtml(title);
String str = new String(seq);
Maybe what both of you told me would work, but it would be complicated.
I have found an easier and more simple solution:
Other parser.
It uses 1 class (vs the sax parser that uses 3 classes), much much easier to understand, and of course, doesn't ignore quotation marks :D
Thanks anyway.
Have you tried to convert quotation marks to an XML entity, before you parse the element?
Several characters have special XML entity references:
& &
< <
> >
" "
' '
I have the ff. XML from a URL:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<Phonebook>
<PhonebookEntry>
<firstname>Michael</firstname>
<lastname>De Leon</lastname>
<Address>5, Cat Street</Address>
</PhonebookEntry>
<PhonebookEntry>
<firstname>John</firstname>
<lastname>Smith</lastname>
<Address>6, Dog Street</Address>
</PhonebookEntry>
</Phonebook>
I want to display both PhonebookEntry values (firstname,lastname,Address). Currently, my code displays only the PhonebookEntry of John Smith (the last entry). Here's my code.
ParsingXML.java
package com.example.parsingxml;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class ParsingXML extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* Create a new TextView to display the parsingresult later. */
TextView tv = new TextView(this);
try {
/* Create a URL we want to load some xml-data from. */
URL url = new URL("http://somedomain.com/jm/sampleXML.xml");
URLConnection ucon = url.openConnection();
/* Get a SAXParser from the SAXPArserFactory. */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
/* Get the XMLReader of the SAXParser we created. */
XMLReader xr = sp.getXMLReader();
/* Create a new ContentHandler and apply it to the XML-Reader*/
ExampleHandler myExampleHandler = new ExampleHandler();
xr.setContentHandler(myExampleHandler);
/* Parse the xml-data from our URL. */
xr.parse(new InputSource(url.openStream()));
/* Parsing has finished. */
/* Our ExampleHandler now provides the parsed data to us. */
ParsedExampleDataSet parsedExampleDataSet =
myExampleHandler.getParsedData();
/* Set the result to be displayed in our GUI. */
tv.setText(parsedExampleDataSet.toString());
} catch (Exception e) {
/* Display any Error to the GUI. */
tv.setText("Error: " + e.getMessage());
}
/* Display the TextView. */
this.setContentView(tv);
}
}
ExampleHandler.java
package com.example.parsingxml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ExampleHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private boolean in_outertag = false;
private boolean in_innertag = false;
private boolean in_firstname = false;
private boolean in_lastname= false;
private boolean in_Address=false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
// ===========================================================
// Getter & Setter
// ===========================================================
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
// ===========================================================
// Methods
// ===========================================================
#Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
#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("PhoneBook")) {
this.in_outertag = true;
}else if (localName.equals("PhonebookEntry")) {
this.in_innertag = true;
}else if (localName.equals("firstname")) {
this.in_firstname = true;
}else if (localName.equals("lastname")) {
this.in_lastname= true;
}else if(localName.equals("Address")) {
this.in_Address= true;
}
}
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("Phonebook")) {
this.in_outertag = false;
}else if (localName.equals("PhonebookEntry")) {
this.in_innertag = false;
}else if (localName.equals("firstname")) {
this.in_firstname = false;
}else if (localName.equals("lastname")) {
this.in_lastname= false;
}else if(localName.equals("Address")) {
this.in_Address= false;
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(this.in_firstname){
myParsedExampleDataSet.setfirstname(new String(ch, start, length));
}
if(this.in_lastname){
myParsedExampleDataSet.setlastname(new String(ch, start, length));
}
if(this.in_Address){
myParsedExampleDataSet.setAddress(new String(ch, start, length));
}
}
}
ParsedExampleDataSet.java
package com.example.parsingxml;
public class ParsedExampleDataSet {
private String firstname = null;
private String lastname=null;
private String Address=null;
//Firstname
public String getfirstname() {
return firstname;
}
public void setfirstname(String firstname) {
this.firstname = firstname;
}
//Lastname
public String getlastname(){
return lastname;
}
public void setlastname(String lastname){
this.lastname=lastname;
}
//Address
public String getAddress(){
return Address;
}
public void setAddress(String Address){
this.Address=Address;
}
public String toString(){
return "Firstname: " + this.firstname + "\n" + "Lastname: " + this.lastname + "\n" + "Address: " + this.Address;
}
}
I'm new to java and android dev, many thanks in advance for any help! :)
The other responses have already pointed out that you require a list to store all the ParsedExampleDataSet objects gotten from the XML.
But I want to point your attention to another thing about XML handlers which may bite you only later (and randomly). The characters method is not a good place to assign the values found between tags in you XML, because the characters method is not guaranteed to return all the characters in an element at once. It may be called multiple times within the same element to report characters found so far. With your implementation as it is right now, you will end up with missing data and wonder what is going on.
That said, what I would do it use a StringBuilder to accumulate your characters and then assign them in an endElement(...) call. Like so:
public class ExampleHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private StringBuilder mStringBuilder = new StringBuilder();
private ParsedExampleDataSet mParsedExampleDataSet = new ParsedExampleDataSet();
private List<ParsedExampleDataSet> mParsedDataSetList = new ArrayList<ParsedExampleDataSet>();
// ===========================================================
// Getter & Setter
// ===========================================================
public List<ParsedExampleDataSet> getParsedData() {
return this.mParsedDataSetList;
}
// ===========================================================
// Methods
// ===========================================================
/** 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("PhonebookEntry")) {
this.mParsedExampleDataSet = new ParsedExampleDataSet();
}
}
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("PhonebookEntry")) {
this.mParsedDataSetList.add(mParsedExampleDataSet);
}else if (localName.equals("firstname")) {
mParsedExampleDataSet.setfirstname(mStringBuilder.toString().trim());
}else if (localName.equals("lastname")) {
mParsedExampleDataSet.setlastname(mStringBuilder.toString().trim());
}else if(localName.equals("Address")) {
mParsedExampleDataSet.setAddress(mStringBuilder.toString().trim());
}
mStringBuilder.setLength(0);
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
mStringBuilder.append(ch, start, length);
}
}
You can then retrieve the list of ParsedExampleDataSets in your activity and either display in multiple text views or only in one. Your Activity.onCreate(...) method may look like:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* Create a new TextView to display the parsingresult later. */
TextView tv = new TextView(this);
try {
/* Create a URL we want to load some xml-data from. */
URL url = new URL("http://somedomain.com/jm/sampleXML.xml");
URLConnection ucon = url.openConnection();
/* Create a new ContentHandler and apply it to the XML-Reader*/
ExampleHandler myExampleHandler = new ExampleHandler();
//remember to import android.util.Xml
Xml.parse(url.openStream(), Xml.Encoding.UTF_8, myExampleHandler);
/* Our ExampleHandler now provides the parsed data to us. */
List<ParsedExampleDataSet> parsedExampleDataSetList =
myExampleHandler.getParsedData();
/* Set the result to be displayed in our GUI. */
for(ParsedExampleDataSet parsedExampleDataSet : parsedExampleDataSetList){
tv.append(parsedExampleDataSet.toString());
}
} catch (Exception e) {
/* Display any Error to the GUI. */
tv.setText("Error: " + e.getMessage());
}
/* Display the TextView. */
this.setContentView(tv);
}
You only have one ParsedExampleDataSet object in your handler, so there's only room to store one entry. Change ExampleHandler to have an ArrayList<ParsedExampleDataSet> results and also a ParsedExampleDataSet currentSet. Inside startElement, when you see the PhoneBook tag, set currentSet to a new instance of ParsedExampleDataSet and add it to results. After parsing, results should contain everything you want.
You were close. Since you have many PhoneBookeEntrys you need to store them somewhere:
public class ExampleHandler extends DefaultHandler{
// ===========================================================
// Fields
// ===========================================================
private boolean in_outertag = false;
private boolean in_innertag = false;
private boolean in_firstname = false;
private boolean in_lastname= false;
private boolean in_Address=false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
private List<ParsedExampleDataSet> allSets = new ArrayList<ParsedExampleDataSet>();
// ===========================================================
// Getter & Setter
// ===========================================================
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
// ===========================================================
// Methods
// ===========================================================
/** 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("PhoneBook")) {
this.in_outertag = true;
}else if (localName.equals("PhonebookEntry")) {
this.in_innertag = true;
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}else if (localName.equals("firstname")) {
this.in_firstname = true;
}else if (localName.equals("lastname")) {
this.in_lastname= true;
}else if(localName.equals("Address")) {
this.in_Address= true;
}
}
/** Gets be called on closing tags like:
* </tag> */
#Override
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
if (localName.equals("Phonebook")) {
this.in_outertag = false;
}else if (localName.equals("PhonebookEntry")) {
this.in_innertag = false;
allSets.add(myParsedExampleDataSet);
}else if (localName.equals("firstname")) {
this.in_firstname = false;
}else if (localName.equals("lastname")) {
this.in_lastname= false;
}else if(localName.equals("Address")) {
this.in_Address= false;
}
}
/** Gets be called on the following structure:
* <tag>characters</tag> */
#Override
public void characters(char ch[], int start, int length) {
if(this.in_firstname){
myParsedExampleDataSet.setfirstname(new String(ch, start, length));
}
if(this.in_lastname){
myParsedExampleDataSet.setlastname(new String(ch, start, length));
}
if(this.in_Address){
myParsedExampleDataSet.setAddress(new String(ch, start, length));
}
}
}
I found an XML tutorial online here and editied it to work with your XML file. Below is the code. For the sake of testing it on my machine, I've sourced the XML file from a local file rather than online, but it shouldn't be too hard to work out.
This should hopefully point you in the right direction.
package phonebook;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class program {
public static void main(String argv[]) {
try {
File file = new File("phonebook.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element " + doc.getDocumentElement().getNodeName());
NodeList nodeLst = doc.getElementsByTagName("PhonebookEntry");
System.out.println("Information of all entries");
for (int s = 0; s < nodeLst.getLength(); s++) {
Node fstNode = nodeLst.item(s);
if (fstNode.getNodeType() == Node.ELEMENT_NODE)
{
Element fstElmnt = (Element) fstNode;
// Firstname
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("firstname");
Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
NodeList fstNm = fstNmElmnt.getChildNodes();
System.out.println("First Name : " + ((Node) fstNm.item(0)).getNodeValue());
// Lastname
NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("lastname");
Element lstNmElmnt = (Element) lstNmElmntLst.item(0);
NodeList lstNm = lstNmElmnt.getChildNodes();
System.out.println("Last Name : " + ((Node) lstNm.item(0)).getNodeValue());
// Address
NodeList addrNmElmntLst = fstElmnt.getElementsByTagName("Address");
Element addrNmElmnt = (Element) addrNmElmntLst.item(0);
NodeList addrNm = addrNmElmnt.getChildNodes();
System.out.println("Address : " + ((Node) addrNm.item(0)).getNodeValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}