Trouble With Xml Parsing Through JAVA
Solution 1:
Using XmlPullParser
following the docs http://developer.android.com/training/basics/network-ops/xml.html
Copied xml to assests folder to parser locally ( for testing only ). You can get the xml from the url and parse.
InputStream is = MainActivity.this.getResources()
.getAssets().open("xmlparser.xml");
new parserPull(is);
Then to parse
public class parserPull
{
private static final String ns = null;
public parserPull(InputStream open) {
try
{
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(open, null);
parser.nextTag();
List<Entry> all = readFeed(parser);
for(int i=0;i<all.size();i++)
{
Log.i("ID is..........",all.get(i).id);
Log.i("Link is........",all.get(i).link);
Log.i("Price is.......",all.get(i).price);
}
}catch(Exception e)
{
e.printStackTrace();
}
}
private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Entry> entry = null;
parser.require(XmlPullParser.START_TAG, ns, "prestashop");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
//Log.i("..................",name);
// Starts by looking for the prestashop tag
if (name.equals("products")) {
entry= readProducts(parser);
} else {
skip(parser);
}
}
return entry;
}
private List<Entry> readProducts(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Entry> entries = new ArrayList<Entry>();
parser.require(XmlPullParser.START_TAG, ns, "products");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// Log.i("..................",name);
// Starts by looking for the products tag
if (name.equals("product")) {
entries.add(readEntry(parser));
} else {
skip(parser);
}
}
return entries;
}
private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "product");
String title = null;
String summary = null;
String link = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// Log.i("...................",name);
if (name.equals("id")) {
title = readId(parser);
} else if (name.equals("id_default_image")) {
summary = readLink(parser);
} else if (name.equals("price")) {
link = readPrice(parser);
} else {
skip(parser);
}
}
return new Entry(title, summary, link);
}
private String readPrice(XmlPullParser parser) throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "price");
String summary = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "price");
return summary;
}
private String readLink(XmlPullParser parser) throws IOException, XmlPullParserException {
String link = "";
parser.require(XmlPullParser.START_TAG, ns, "id_default_image");
String tag = parser.getName();
// Log.i("............",tag);
String relType = parser.getAttributeValue(null, "not_filterable");
if (tag.equals("id_default_image")) {
if (relType.equals("true")){
link = parser.getAttributeValue(null, "xlink:href");
parser.nextTag();
}
}
parser.require(XmlPullParser.END_TAG, ns, "id_default_image");
return link;
}
private String readId(XmlPullParser parser) throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "id");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "id");
return title;
}
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
public static class Entry {
public final String id;
public final String link;
public final String price;
private Entry(String id, String link, String price) {
this.id = id;
this.link = link;
this.price = price;
}
}
}
The log output
12-10 03:29:44.664: I/ID is..........(1511): 5
12-10 03:29:44.664: I/Link is........(1511): https://www.10ngah.com/api/images/products/5/5
12-10 03:29:44.674: I/Price is.......(1511): 525
12-10 03:29:44.674: I/ID is..........(1511): 6
12-10 03:29:44.674: I/Link is........(1511): https://www.10ngah.com/api/images/products/6/6
12-10 03:29:44.674: I/Price is.......(1511): 525
Solution 2:
First your example has syntax error (missing space before attribute)...
I like a JAXB very much... so I would recomend it to you. If your data has static format (not change format in time) it is the best way. Only "problem" could be with CDATA blocks, see this post for more information. Here is "fast" example... it is not nice code just a example!
public class AdapterCDATA extends XmlAdapter {
@Override
public String marshal(String arg0) throws Exception {
return "";
}
@Override
public String unmarshal(String arg0) throws Exception {
return arg0;
}
}
public class TestData {
@XmlRootElement(name = "prestashop")
@XmlAccessorType(XmlAccessType.FIELD)
static class Prestashop {
@XmlElementWrapper(name = "products")
@XmlElement(name = "product")
List products;
}
@XmlAccessorType(XmlAccessType.FIELD)
static class Product {
@XmlJavaTypeAdapter(AdapterCDATA.class)
@XmlElement(name = "id")
String id;
@XmlElement(name = "id_default_image")
IdDefaultImage idDefaultImage;
@XmlJavaTypeAdapter(AdapterCDATA.class)
@XmlElement(name = "price")
String price;
@XmlElement(name = "name")
Name name;
}
@XmlAccessorType(XmlAccessType.FIELD)
static class IdDefaultImage {
@XmlAttribute(name = "not_filterable")
String notFilterable;
@XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
String href;
@XmlJavaTypeAdapter(AdapterCDATA.class)
@XmlValue
String idDefaultImage;
}
@XmlAccessorType(XmlAccessType.FIELD)
static class Name {
@XmlElement(name = "language")
Language language;
}
@XmlAccessorType(XmlAccessType.FIELD)
static class Language {
@XmlJavaTypeAdapter(AdapterCDATA.class)
@XmlValue
String language;
@XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
String href;
@XmlAttribute(name = "id")
String id;
}
public static void main(String[] args) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(Prestashop.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/test/resources/testData.xml");
Prestashop prestashop = (Prestashop) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(prestashop, System.out);
}
}
Solution 3:
EXAMPLE XML:
<a>
<b category='3' number='25' points='2'>
<c>
<d filename='' content='some content'/>
<d filename='0134.jpg'/>
</c>
<e>
<f description='desc' correct='1'/>
</e>
</a>
CODE FOR PARSING
Fields in parsing class to make later modification easier:
//data to parse
private static final String TAG_A = "a"; //root
private static final String TAG_B = "b";
private static final String ATT_CATEGORY = "category";
private static final String ATT_POINTS = "points";
private static final String TAG_D = "d";
private static final String ATT_FILE_NAME = "filename";
private static final String ATT_CONTENT = "content";
private static final String TAG_F = "f";
private static final String ATT_DESCRIPTION = "description";
private static final String ATT_CORRECT = "correct";
Method in parsing class:
private void parseXml()
{
try
{
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(questionsXmlFile, null);
parser.nextTag();
parser.require(XmlPullParser.START_TAG, null, TAG_A);
while (parser.next() != XmlPullParser.END_DOCUMENT)
{
if (parser.getEventType() == XmlPullParser.START_TAG)
{
String name = parser.getName();
if (name.equalsIgnoreCase(TAG_B))
{
parser.getAttributeValue(null, ATT_CATEGORY));
parser.getAttributeValue(null, ATT_POINTS));
}
else if (name.equalsIgnoreCase(TAG_D))
{
parser.getAttributeValue(null, ATT_CONTENT));
parser.getAttributeValue(null, ATT_FILE_NAME));
}
else if (name.equalsIgnoreCase(TAG_ANSWER))
{
}
}
}
}
catch (XmlPullParserException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
What this method does?
It traverse through xml from beginning to END_DOCUMENT
and check if tags has been found are interesting one. If yes, check desired attributes and do nothing with it (add your own actions.
Remember, getAttributeValue()
can return null. Be sure you dont operate on null
.
Remember, parser.require(XmlPullParser.START_TAG, null, TAG_A)
returns exception if variables passed to it are wrong comparing current situation of parser.
Solution 4:
Your code looks all ok, only you have to remove <![CDATA[ .... ]]>
<id><![CDATA[ 526 ]]></id> change to <id>526</id>
or if you do not want to remove it, then do it following way,
Add the following method/function:
public String getCDataValue(Element e, String id) {
NodeList title = e.getElementsByTagName(id);
Element ex = (Element) title.item(0);
Node child = ex.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData().trim();
}
return "";
}
and then use it this way:
NodeList nl = doc.getElementsByTagName("product");
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
Toast.makeText(getApplicationContext(), getCDataValue(e, "price"),
Toast.LENGTH_SHORT).show();
}
if its is your code :
publishProgress(new ProductItems(
getCDataValue(e, "name"),
getCDataValue(e, "id"),
getCDataValue(e, "id_default_image"),
12.050000)
);
Post a Comment for "Trouble With Xml Parsing Through JAVA"