Android Studio XmlPullParser parsing multiply nested elements - android

My XML file is something like this:
<Items>
<Nested_item>
<id>1</id>
<name>nested</name>
<description>
<desc_item>1</desc_item>
<desc_item>2</desc_item>
<desc_item>3</desc_item>
</description>
</Nested_item>
<Nested_item>
<id>2</id>
<name>nested2</name>
<description>
<desc_item>1</desc_item>
<desc_item>2</desc_item>
<desc_item>3</desc_item>
</description>
</Nested_item>
<Nested_item>
<id>3</id>
<name>nested3</name>
<description>
<desc_item>1</desc_item>
<desc_item>2</desc_item>
<desc_item>3</desc_item>
</description>
</Nested_item>
</Items>
and I have class Items with atributes which I've putted into ArrayList, I've managed to parse all atributes except desc_item (which I need as ArrayList for every Item object). How can I tell parser to take only third item, for example, and to get those desc_item values as String?

I found solution to my problem, i have parsed inner data and after that i have parsed particular data:
private ArrayList<Proizvod> parseXML (XmlPullParser parser) throws XmlPullParserException, IOException {
ArrayList<Proizvod> proizvodLista = null;
int eventType = parser.getEventType();
Proizvod proizvod = null;
while(eventType != XmlPullParser.END_DOCUMENT){
String name;
switch (eventType){
case XmlPullParser.START_DOCUMENT:
proizvodLista = new ArrayList<Proizvod>();
break;
case XmlPullParser.START_TAG:
name = parser.getName();
//System.out.println(name);
if(name.equals("Proizvod")){
proizvod = new Proizvod();
proizvod.setId(parser.getAttributeValue(null, "id"));
}else if(proizvod != null){
if(name.equalsIgnoreCase("ime_proizvoda")){
proizvod.setIme_proizvoda(parser.nextText());
}else if(name.equalsIgnoreCase("vrsta_proizvoda")){
proizvod.setVrsta_proizvoda(parser.nextText());
}else if(name.equalsIgnoreCase("merna_jedinica")){
proizvod.setVrsta_proizvoda(parser.nextText());
}else if(name.equalsIgnoreCase("Prodavnice")){
proizvod.setLista_prodavnica(parsing(parser));
}
}
break;
case XmlPullParser.END_TAG:
name = parser.getName();
if(name.equalsIgnoreCase("proizvod")&& proizvod !=null){
proizvodLista.add(proizvod);
}
}
eventType = parser.next();
}
return proizvodLista;
}
private ArrayList<String> parsing (XmlPullParser parser) throws XmlPullParserException, IOException {
String print = null;
int eventType = parser.getEventType();
ArrayList<String> lista = new ArrayList<String>();
while(eventType != XmlPullParser.END_DOCUMENT){
String name = parser.getName();
if(name.equalsIgnoreCase("Prodavnice")){break;}
else{
if(eventType==XmlPullParser.START_TAG){
print = parser.nextText();
lista.add(print);
System.out.println(print);
}
}
eventType = parser.next();
}
return lista;
}
And my XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Proizvodi>
<Proizvod id="1">
<ime_proizvoda>Mleko</ime_proizvoda>
<vrsta_proizvoda>mlecni proizvod</vrsta_proizvoda>
<merna_jedinica>litar</merna_jedinica>
<Prodavnice>
<Prodavnica>1</Prodavnica>
<Prodavnica>3</Prodavnica>
<Prodavnica>4</Prodavnica>
</Prodavnice>
</Proizvod>
<Proizvod id="2">
<ime_proizvoda>Hleb</ime_proizvoda>
<vrsta_proizvoda>Pekarski proizvod</vrsta_proizvoda>
<merna_jedinica>gram</merna_jedinica>
<Prodavnice>
<Prodavnica>1</Prodavnica>
<Prodavnica>2</Prodavnica>
<Prodavnica>3</Prodavnica>
</Prodavnice>
</Proizvod>
<Proizvod id="3">
<ime_proizvoda>Suvi vrat</ime_proizvoda>
<vrsta_proizvoda>Mesna preradjevina</vrsta_proizvoda>
<merna_jedinica>gram</merna_jedinica>
<Prodavnice>
<Prodavnica>2</Prodavnica>
<Prodavnica>3</Prodavnica>
<Prodavnica>4</Prodavnica>
</Prodavnice>
</Proizvod>
<Proizvod id="4">
<ime_proizvoda>Pecenica</ime_proizvoda>
<vrsta_proizvoda>Mesna preradjevina</vrsta_proizvoda>
<merna_jedinica>100 grama</merna_jedinica>
<Prodavnice>
<Prodavnica>1</Prodavnica>
<Prodavnica>2</Prodavnica>
<Prodavnica>4</Prodavnica>
</Prodavnice>
</Proizvod>

Related

Trying to pull and play an mp3 file from RSS feed in android app

I'm trying to make an app for a podcast. My end goal is for a user to be able to click on an episode in a list (which is generated from an RSS feed) and then have the audio play (which is also retrieved from the RSS feed) My problem is with parsing the XML from the RSS feed. I can't seem to figure out how to get the URL out of the enclosure tag for the mp3. Any help would be appreciated. Here is my parsing class
private String data;
private ArrayList<Episodes> mEpisodes;
public ParseEpisodes(String xmlData) {
this.data = xmlData;
mEpisodes = new ArrayList<>();
}
public ArrayList<Episodes> getEpisodes() {
return mEpisodes;
}
public boolean process(){
boolean status = true;
Episodes currentRecord = null;
boolean inEntry = false;
String textValue = "";
String urlValue = "";
try{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new StringReader(this.data));
int eventType = xpp.getEventType();
while(eventType != XmlPullParser.END_DOCUMENT){
String tagName = xpp.getName();
switch(eventType){
case XmlPullParser.START_TAG:
//Log.d("ParseEpisodes", "Starting tag for " + tagName);
if(tagName.equalsIgnoreCase("item")){
inEntry = true;
currentRecord = new Episodes();
}
break;
case XmlPullParser.TEXT:
textValue = xpp.getText();
urlValue = xpp.getText();
break;
case XmlPullParser.END_TAG:
//Log.d("ParseEpisodes", "Ending tag for " + tagName);
if(inEntry){
if(tagName.equalsIgnoreCase("item")){
mEpisodes.add(currentRecord);
inEntry = false;
}else if(tagName.equalsIgnoreCase("title")){
currentRecord.setTitle(textValue);
}else if(tagName.equalsIgnoreCase("enclosure")){
currentRecord.setLink(urlValue);
}
}
break;
}
eventType = xpp.next();
}
}catch (Exception e){
status = false;
e.printStackTrace();
}
return true;
}
here is the xml
<item>
<title>Episode 52 - Facebook Nukes The Show</title>
<link>https://greynoi.se/podcasts/episode-52-facebook-nukes-the-show</link>
<enclosure url="http://greynoi.se/episodes/ep79_m.mp3" length="43312404" type="audio/mpeg"/>
<pubDate>Fri, 15 Jul 2016 15:22:24 -0700</pubDate>
<category>1</category>
<source url="https://greynoi.se">The GR3YNOISE Podcast</source>
<itunes:subtitle>Episode 52 - Facebook Nukes The Show</itunes:subtitle>
<itunes:summary>Episode 52 - Facebook Nukes The Show</itunes:summary>
<content:encoded><![CDATA[Episode 52 - Facebook Nukes The Show"}]]></content:encoded>
<guid>https://greynoi.se/podcasts/episode-52-facebook-nukes-the-show</guid>
</item>
So you want the url after the enclosure url= tag?
If that is the case it is very easy. Just use substrings to find and get the url.
Something like this should work.
int urlTagStart = text.indexOf("<enclosure url="");
int urlTagEnd = text.indexOf(".mp3");
String url = text.substring(urlTagStart + 16, urlTagEnd + 4)
Try this:
...
YOUR CODE
...
while(eventType != XmlPullParser.END_DOCUMENT){
String tagName = xpp.getName();
if (tagName.equalsIgnoreCase("enclosure")) {
int attributeCount = xpp.getAttributeCount();
for(int i = 0; i<attributeCount; i++){
String attrib = xpp.getAttributeName(i);
if(attrib && attrib.equalsIgnoreCase("url")){
String url = xpp.getAttributeValue(i);
}
}
}
if (url != null && !url.isEmpty() && !url.equals("null")) {
Log.d("ParseEpisodes", "URL to mp3: " + url);
}
...
THE REST OF YOUR CODE
...
}
The solution to this ended up being pretty simple. All I needed to do was delete
urlValue = xpp.getText();
from the
case XmlPullParser.TEXT:
Then change
else if(tagName.equalsIgnoreCase("enclosure")){
urlValue = xpp.getAttributeValue(0);
currentRecord.setLink(urlValue);
}
in the
case XmlPullParser.END_TAG:

How to parse xml response in android?

In my application i am receiving the below Httpresponse from a webservice in xml format.
<?xml version="1.0" encoding="UTF-8"?>
<results>
<result>
<status>0</status>
<messageid>213123</messageid>
<destination>1234567890</destination>
</result>
</results>
I tried parsing the response in the below format :
private void parseXML(XmlPullParser parser) throws XmlPullParserException,IOException
{
ArrayList<SMSResponse> products = null;
int eventType = parser.getEventType();
SMSResponse currentProduct = null;
while (eventType != XmlPullParser.END_DOCUMENT){
Log.e("ENTER-", "while loop");
String name = null;
switch (eventType){
case XmlPullParser.START_DOCUMENT:
products = new ArrayList<SMSResponse>();
Log.e("ENTER-", "swicth case -1");
break;
case XmlPullParser.START_TAG:
name = parser.getName();
Log.e("start name", name);
if(name.equals("results"))
{
Log.e("start name", name);
}
else if(name.equals("result"))
{
Log.e("start name", name);
currentProduct = new SMSResponse();
}
else if(name.equals("status"))
{
Log.e("start name", name);
System.out.println("status value==");
currentProduct.status = parser.getProperty(name).toString();
}
else if(name.equals("messageid"))
{
Log.e("start name", name);
System.out.println("messageid value=="+ parser.getProperty(name));
currentProduct.messageid = parser.getProperty(name).toString();
}
else if(name.equals("destination"))
{
Log.e("start name", name);
System.out.println("destination value=="+ parser.getProperty(name));
currentProduct.destination = parser.getProperty(name).toString();
}
break;
case XmlPullParser.END_TAG:
name = parser.getName();
Log.e("end name", name);
// Log.e("ENTER-", "switch case-3");
if (name.equalsIgnoreCase("results") ){
Log.e("end name", name);
products.add(currentProduct);
}
}
eventType = parser.next();
}
Log.e("Array", products.toString());
// printProducts(products);
}
But i am getting null response as the value.
How do i extract the value of the xml header?
Please Help ! Thanks in Advance!
Following is the code snippet for handling XML operations. I am using XML parser class so far we built and looping through each XML element and getting the child data.
static final String KEY_RESULT = "result"; // parent node
static final String KEY_STATUS = "status";
static final String KEY_MESSAGE_ID = "messageid";
static final String KEY_DESC = "description";
XMLParser parser = new XMLParser();
//xml getting from url
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_RESULT);
// looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
String name = parser.getValue(e, KEY_STATUS); // name child value
String cost = parser.getValue(e, KEY_MESSAGE_ID); // cost child value
String description = parser.getValue(e, KEY_DESC); // description child value
}

Process tags in description , Android, RSS, XML parser

I have a little problem with my Android RSS reader. I am using XML parser to get tags from RSS feed, but sometimes, in description, i have many of them - like, <description> <img src="some random url"><table..., e.t.c. I want to process them, esp. the IMG tag.How can i procees all of them (becuase now i have a bunch of unparsed code in description).Here is a read function from my parser class.
private List<RssItem> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, null, "rss");
String title = null;
String link = null;
String description = null;
String pubDate = null;
String url = null;
List<RssItem> items = new ArrayList<RssItem>();
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("title")) {
title = readTitle(parser);
} else if (name.equals("link")) {
link = readLink(parser);
}
else if(name.equals("description")) {
description = readDescription(parser);
}
else if(name.equals("pubDate")) {
pubDate = readPubDate(parser);
}
if (title != null && link != null) {
RssItem item = new RssItem(title, link, description, pubDate, url);
items.add(item);
title = null;
link = null;
description = null;
pubDate = null;
url = null;
}
}
return items;
}
private String readDescription(XmlPullParser parser) throws XmlPullParserException, IOException{
parser.require(XmlPullParser.START_TAG, ns, "description");
String description = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "description");
return description;
}
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
Thank you in advance for your answer
I had similar issue, part of solution you can take description as a string and pass it to method that return String array to represent parameters. jsoup library could help to extract image link. still doesn't know if it could extract other parameters.
here is what I did so far.
public String[] stripHtml(String html) {
Document document = Jsoup.parse(html);
String picLink = document.select("img").first().attr("src");
String result = Html.fromHtml(html).toString();
result = result.substring(0, result.indexOf('['));
String[] linkAndDescription = {picLink, result};
return linkAndDescription;
}
EDIT
this is the full solution for my situation, I want to parse image link and description text.
public String[] stripHtml(String html) {
Document document = Jsoup.parse(html);
//piclink
String picLink = document.select("img").first().attr("src");
//description
String text = document.select("p").first().text();
text = text.substring(0, text.indexOf('['));
String[] linkAndDescription = {picLink, text};
return linkAndDescription;
}

Parse author tag using XmlPullParser

In one of my projects that i'm working off i'm trying to parse all feeds from an atom xml as this below.
<entry>
<id>tag:blogger.com,1999:blog-4512083858574973357.post-3473864646179740942</id>
<published>2015-09-14T09:28:00.000+03:00</published>
<updated>2015-09-14T15:30:18.832+03:00</updated>
<title type="text">Mytitle</title>
<content>Hello</content>
<author>
<name>Author name</name>
<uri>URI HERE</uri>
<email>EMAIL HERE</email>
<gd:image rel="" width="32" height="32" src="" />
</author>
I can get all tags using the following code but i have no idea how to parse the name of the author.
private Entry readEntry(XmlPullParser parser)
throws XmlPullParserException, IOException, ParseException {
parser.require(XmlPullParser.START_TAG, ns, "entry");
String id = null;
String title = null;
Uri image = null;
String link = null;
String content = null;
String description;
String author = null;
String shortDescription = null;
ArrayList tags= new ArrayList<>();;
long publishedOn = 0;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
switch (name) {
case "id":
id = readTag(parser, TAG_ID);
break;
case "title":
title = readTag(parser, TAG_TITLE);
break;
case "link":
link = readTag(parser, TAG_LINK);
break;
case "author":
//****************************************************
CANT GET THE NAME OF THE AUTHOR HERE
//****************************************************
break;
case "category": {
String tempLink = readTag(parser, TAGS);
if (tempLink != null) {
tags.add(tempLink);
}
break;
}
case "content": {
String tempLink = readTag(parser, TAG_CONTENT);
if (tempLink != null) {
content = tempLink;
image = Uri.parse(pullImageLink(content));
description = Html.fromHtml(content.replaceAll("<img.+?>", "")).toString().trim();
if (description.length() > 0) {
int descrLength = description.length();
if (descrLength > 250) {
shortDescription = description.substring(0, 250);
} else {
shortDescription = description.substring(0, descrLength);
}
}
}
break;
}
case "published":
publishedOn = getParsedDate(readTag(parser, TAG_PUBLISHED));
break;
default:
skip(parser);
break;
}
}
assert image != null;
return new Entry(id, title, image.toString(), link, content, shortDescription, publishedOn,tags, author);
}

XmlPullParser view special alphabetical characters

I've done XML parsing via XmlPullParser and it works fine until I add special characters to my xml file such as š,č,ř,ž and so on. It replaces the character with "?" sign. Is there any way how to get rid of that?
Here is my Xml parser class:
public class ClubsXmlPullParser {
static final String CLUB = "club";
static final String NAME = "name";
static final String ABOUT = "about";
static final String STADIUM = "stadium";
static final String LOGO = "logo";
static final String MOREABOUT = "moreAbout";
public static List<LeagueClub> getItemsFromFile(Context ctx) {
List<LeagueClub> clubs;
clubs = new ArrayList<LeagueClub>();
LeagueClub curItem = null;
String curText = "";
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
FileInputStream fis = ctx.openFileInput("clubs.xml");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
xpp.setInput(reader);
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String tagname = xpp.getName();
switch (eventType) {
case XmlPullParser.START_TAG:
if (tagname.equalsIgnoreCase(CLUB)) {
curItem = new LeagueClub();
}
break;
case XmlPullParser.TEXT:
curText = xpp.getText();
break;
case XmlPullParser.END_TAG:
if (tagname.equalsIgnoreCase(CLUB)) {
clubs.add(curItem);
} else if (tagname.equalsIgnoreCase(NAME)) {
curItem.setName(curText);
} else if (tagname.equalsIgnoreCase(ABOUT)) {
curItem.setAbout(curText);
} else if (tagname.equalsIgnoreCase(STADIUM)) {
curItem.setStadium(curText);
} else if (tagname.equalsIgnoreCase(LOGO)) {
curItem.setLogo(curText);
} else if (tagname.equalsIgnoreCase(MOREABOUT)) {
curItem.setName(curText);
}
break;
default:
break;
}
eventType = xpp.next();
}
} catch (Exception e) {
e.printStackTrace();
}
return clubs;
}
}
Assuming that you know how to obtain the encoding of the file, you can use the alternative version of setInput - setInput(InputStream inputStream, String inputEncoding)

Categories

Resources