How to use xml with android application? - android

I am currently creating my first android application
i never used it before
What i need is to read xml file from the internet and put it in a list
( to read this xml http://pollsdb.com/test.txt and put the results in list )
i will appreciate if someone can post a code that works

XML Pull Parser is an interface that defines parsing functionality provided in XMLPULL V1 API .
There are following different kinds of parser depending on which features are set:
non-validating parser as defined in XML 1.0 spec when FEATURE_PROCESS_DOCDECL is set to true
validating parser as defined in XML 1.0 spec when FEATURE_VALIDATION is true (and that implies that FEATURE_PROCESS_DOCDECL is true)
when FEATURE_PROCESS_DOCDECL is false (this is default and if different value is required necessary must be changed before parsing is started) then parser behaves like XML 1.0 compliant non-validating parser under condition that no DOCDECL is present in XML documents (internal entites can still be defined with defineEntityReplacementText()). This mode of operation is intended for operation in constrained environments such as J2ME.
There are two key methods: next() and nextToken(). While next() provides access to high level parsing events, nextToken() allows access to lower level tokens.
The current event state of the parser can be determined by calling the getEventType() method. Initially, the parser is in the START_DOCUMENT state.
The method next() advances the parser to the next event. The int value returned from next determines the current parser state and is identical to the value returned from following calls to getEventType ().
Th following event types are seen by next()
START_TAG
An XML start tag was read.
TEXT
Text content was read; the text content can be retrieved using the getText() method. (when in validating mode next() will not report ignorable whitespace, use nextToken() instead)
END_TAG
An end tag was read
END_DOCUMENT
No more events are available
after first next() or nextToken() (or any other next*() method) is called user application can obtain XML version, standalone and encoding from XML declaration in following ways:
version: getProperty("http://xmlpull.org/v1/doc/properties.html#xmldecl-version") returns String ("1.0") or null if XMLDecl was not read or if property is not supported
standalone: getProperty("http://xmlpull.org/v1/doc/properties.html#xmldecl-standalone") returns Boolean: null if there was no standalone declaration or if property is not supported otherwise returns Boolean(true) if standalone="yes" and Boolean(false) when standalone="no"
encoding: obtained from getInputEncoding() null if stream had unknown encoding (not set in setInputStream) and it was not declared in XMLDecl
A minimal example for using this API may look as follows:
import java.io.IOException;
import java.io.StringReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class SimpleXmlPullApp
{
public static void main (String args[])
throws XmlPullParserException, IOException
{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput( new StringReader ( "<foo>Hello World!</foo>" ) );
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_DOCUMENT) {
System.out.println("Start document");
} else if(eventType == XmlPullParser.START_TAG) {
System.out.println("Start tag "+xpp.getName());
} else if(eventType == XmlPullParser.END_TAG) {
System.out.println("End tag "+xpp.getName());
} else if(eventType == XmlPullParser.TEXT) {
System.out.println("Text "+xpp.getText());
}
eventType = xpp.next();
}
System.out.println("End document");
}
}
The above example will generate the following output:
Start document
Start tag foo
Text Hello World!
End tag foo
EDIT THE CODE TO YOUR NEEDS :)

Related

How do I properly handle namespaces using XmlPullParser in Android, while parsing XML?

I'll try to be brief as possible. I am trying to process KML (XML) files using the XmlPullParser in my Android application. I've got it working fairly well, but am getting hung up with the namespaces.
I initiate my parser like so:
public void parse(FileInputStream in) throws XmlPullParserException, IOException {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
XmlPullParser parser = factory.newPullParser();
parser.setInput(in, null);
parser.nextTag();
readKML(parser);
} finally {
in.close();
}
}
Next, the program steps through the various tag checks I set up, and properly returns all the values UNTIL it gets to the part of the XML that uses namespaces (xal):
<Folder>
<name>Family & Friends</name>
<description>Locations of family members and friends.</description>
<Placemark>
<name>Fred and Marthas House</name>
<description></description>
<Point>
<coordinates>-55.55559,55.55555,120.0</coordinates>
</Point>
<xal:AddressDetails>
<xal:Country>
<xal:CountryName>United States</xal:CountryName>
<xal:CountryNameCode>US</xal:CountryNameCode>
<xal:AdministrativeArea>
<xal:AdministrativeAreaName>Michigan</xal:AdministrativeAreaName>
<xal:Locality>
<xal:LocalityName>Lawton</xal:LocalityName>
<xal:Thoroughfare>
<xal:ThoroughfareNumber></xal:ThoroughfareNumber>
<xal:ThoroughfareName>45th Street</xal:ThoroughfareName>
</xal:Thoroughfare>
<xal:PostalCode>
<xal:PostalCodeNumber></xal:PostalCodeNumber>
</xal:PostalCode>
</xal:Locality>
</xal:AdministrativeArea>
</xal:Country>
</xal:AddressDetails>
I process each individual XML value like this:
// Processes title tags in the feed.
private String readCountryNameCode(XmlPullParser parser) throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, NS, G.KML.COUNTRY_NAME_CODE);
String countryCode = readText(parser);
Log.d(TAG, "Found CountryNameCode value under Country tag");
parser.require(XmlPullParser.END_TAG, NS, G.KML.COUNTRY_NAME_CODE);
return countryCode;
}
Once it gets to the namespace portion of the xml it starts getting angry. The stacktrace says:
2018-12-24 12:59:43.026 1884-2314/OBFUSCATED_PERSONAL_INFO W/System.err: org.xmlpull.v1.XmlPullParserException: expected: START_TAG {null}CountryNameCode (position:END_TAG </{urn:oasis:names:tc:ciq:xsdschema:xAL:2.0}xal:Country>#30:21 in java.io.InputStreamReader#9f81207)
2018-12-24 12:59:43.027 1884-2314/OBFUSCATED_PERSONAL_INFO W/System.err: at org.kxml2.io.KXmlParser.require(KXmlParser.java:2067)
2018-12-24 12:59:43.027 1884-2314/OBFUSCATED_PERSONAL_INFO W/System.err: at OBFUSCATED_PERSONAL_INFO.KML_Import_Pull.readCountryNameCode(KML_Import_Pull.java:470)
So, next, I specified the namespace explicitly in the .require statement where the values are read:
// Processes title tags in the feed.
private String readCountryNameCode(XmlPullParser parser) throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, "xal", G.KML.COUNTRY_NAME_CODE);
String countryCode = readText(parser);
Log.d(TAG, "Found CountryNameCode value under Country tag");
parser.require(XmlPullParser.END_TAG, "xal", G.KML.COUNTRY_NAME_CODE);
return countryCode;
}
The stacktrace changed slightly, but is still more or less the same error:
2018-12-24 13:12:48.615 3842-4769/OBFUSCATED_PERSONAL_INFO W/System.err: org.xmlpull.v1.XmlPullParserException: expected: START_TAG {xal}CountryNameCode (position:START_TAG <{urn:oasis:names:tc:ciq:xsdschema:xAL:2.0}xal:CountryNameCode>#16:29 in java.io.InputStreamReader#eaf421)
2018-12-24 13:12:48.615 3842-4769/OBFUSCATED_PERSONAL_INFO W/System.err: at org.kxml2.io.KXmlParser.require(KXmlParser.java:2067)
2018-12-24 13:12:48.615 3842-4769/OBFUSCATED_PERSONAL_INFO W/System.err: at OBFUSCATED_PERSONAL_INFO.KML_Import_Pull.readCountryNameCode(KML_Import_Pull.java:470)
My only other thought is that the XML is malformed, but other applications process it just fine, and at least the first several entries appear well formed. I went through them manually as well as using another application to double check. edit I used an online xml validator and it didn't give any errors while checking the document
Did I miss anything setting up the XmlPullParser factory preparing it for this xal namespace?
The problem was programmatic, I had two erroneously placed parser.nextTag further up the tree that caused the errors.

cannot receive new created chats when adding custom IQProvider to Asmack

im using asmack-android-17-0.8.3 for my android project.
i have copied the asmack source into my project and i have also added my custom IQ provider at ConfigureProviderManager class like this:
other extensions and IQ providers...
// XEP-184 Message Delivery Receipts
pm.addExtensionProvider("received", "urn:xmpp:receipts", new DeliveryReceipt.Provider());
pm.addExtensionProvider("request", "urn:xmpp:receipts", new DeliveryReceipt.Provider());
// XEP-0115 Entity Capabilities
pm.addExtensionProvider("c", "http://jabber.org/protocol/caps", new CapsExtensionProvider());
// XEP-0136
pm.addIQProvider("list", "urn:xmpp:archive", new ListIQProvider());
as you can see, at the most bottom line, i have added IQProvider to support archiving in XEP-0136!
now, when i add this, i can get the archived chat data to my iq provider, but unfortunately at the same time it also make my client unable to receive new chats through the ChatManager!
is this still bug in asmack? what is the best way to add my custom iqprovider?
please give me suggestion how to solve this. thanks!
Did you see this sentence from docs “Parse the IQ sub-document and create an IQ instance. Each IQ must have a single child element. At the beginning of the method call, the xml parser will be positioned at the opening tag of the IQ child element. At the end of the method call, the parser must be positioned on the closing tag of the child element.”?
Maybe you should write your code like the smack built-in provider MUCAdminProvider:
boolean done = false;
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("actor")) {
item.setActor(parser.getAttributeValue("", "jid"));
}
if (parser.getName().equals("reason")) {
item.setReason(parser.nextText());
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("item")) {
done = true;
}
}
}

Android Html.fromHtml() loses the HTML if it starts with <p> tag

i call a web service that returns some HTML which enclosed in an XML envelop... something like:
<xml version="1.0" cache="false">
<text color="white">
<p> Some text <br /> <p>
</text>
</xml>
I use XmlPullParser to parse this XML/HTML. To get the text in element, i do the following:
case XmlPullParser.START_TAG:
xmlNodeName = parser.getName();
if (xmlNodeName.equalsIgnoreCase("text")) {
String color = parser.getAttributeValue(null, "color");
String text = parser.nextText();
if (color.equalsIgnoreCase("white")) {
detail.setDetail(Html.fromHtml(text).toString());
}
}
break;
This works well and gets the text or html in element even if it contains some html tags.
Issue arises when the element's data starts with <p> tag as in above example. in this case the data is lost and text is empty.
How can i resolve this?
EDIT
Thanks to Nik & rajesh for pointing out that my service's response is actually not a valid XML & element not closed properly. But i have no control over the service so i cannot edit whats returned. I wonder if there is something like HTML Agility that can parse any type of malformed HTML or can at least get whats in html tags .. like inside <text> ... </text> in my case?? That would also be good.
OR anything else that i can use to parse what i get from the service will be good as long as its decently implementable.
Excuse me for my bad english
You are seeing that behavior because what you have inside the <text>...</text> tags is not a text element, but an XML Node element. You should enclose the contents in a CDATA section.
Edit: Providing the code segment for my suggestion in the comment. It does indeed work with the sample XML given by you.
StringBuffer html = new StringBuffer();
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_TAG) {
String name = parser.getName();
if(name.equalsIgnoreCase("text")){
isText = true;
}else if(isText){
html.append("<");
html.append(name);
html.append(">");
}
} else if(eventType == XmlPullParser.END_TAG) {
String name = parser.getName();
if(name.equalsIgnoreCase("text")){
isText = false;
}else if(isText){
html.append("</");
html.append(name);
html.append(">");
}
} else if(eventType == XmlPullParser.TEXT) {
if(isText){
html.append(parser.getText());
}
}
eventType = parser.next();
}
Because above code you don't close "</p>" TAG.
<p> Some text <br /> </p>
Used this line .
Solution
Isnpired by Martin's approach of converting the received data first to string, i managed my problem in a kind of mixed approach.
Convert the received InputStream's value to string and replaced the erroneous tag with "" (or whatever you wish) : as follows
InputStreamReader isr = new InputStreamReader(serviceReturnedStream);
BufferedReader br = new BufferedReader(isr);
StringBuilder xmlAsString = new StringBuilder(512);
String line;
try {
while ((line = br.readLine()) != null) {
xmlAsString.append(line.replace("<p>", "").replace("</p>", ""));
}
} catch (IOException e) {
e.printStackTrace();
}
Now i have a string which contains correct XML data (for my case), so just use the normal XmlPullParser to parse it instead of manually parsing it myself:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser parser = factory.newPullParser();
parser.setInput(new StringReader(xmlAsString.toString()));
Hope this helps someone!

how to parse xml from EditText?

i try to build an application with xml parser.
ex : http://www.androidpeople.com/android-xml-parsing-tutorial-using-saxparser
but i want to parse xml file from EditText, how it work ?
Change this line:
xr.parse(new InputSource(sourceUrl.openStream()));
to
String xmlString = editText.getText().toString();
StringReader reader = new StringReader(xmlString);
xr.parse(new InputSource(reader));
You have several ways to parse XML, the most widely used being SAX and DOM. The choice is quite strategical as explained in this paper.
Here is a short explanation of SAX:
You will need some imports:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import android.util.Xml;
Create your own XML SAX DefaultHandler:
class MySaxHandler extends DefaultHandler {
// Override the methods of DefaultHandler that you need.
// See [this link][3] to see these methods.
// These methods are going to be called while the XML is read
// and will allow you doing what you need with the content.
// Two examples below:
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// This is called each time an openeing XML tag is read.
// As the tagname is passed by parameter you know which tag it is.
// You also have the attributes of the tag.
// Example <mytag myelem="12"> will lead to a call of
// this method with the parameters:
// - localName = "mytag"
// - attributes = { "myelem", "12" }
}
public void characters(char[] ch, int start, int length) throws SAXException {
// This is called each time some text is read.
// As an example, if you have <myTag>blabla</myTag>
// this will be called with the parameter "blabla"
// Warning 1: this is also called when linebreaks are read and the linebreaks are passed
// Warning 2: you have to memorize the last open tag to determine what tag this text belongs to (I usually use a stack).
}
}
Extract the XML as a String from the EditText. Let's call it xmlContent
Create and initialize your XML parser:
final InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(xmlContent.getBytes()));
final MySaxHandler handler = new MySaxHandler();
And then, make the XML content to be read by the parser. This will lead your MySaxHandler to have its various method called while the reading is in progress.
Xml.parse(reader, handler);

XmlPullParser how to attain res/raw/xml/xmlfilename?

I am new to programming, so to start with correct me if I am wrong in the paragragh below :
There is mainly three xml parsers for use in Android : Sax, Dom, and XmlPullParser. That last option, while existing as an external ressource. Is "in the core" of Android, thus working faster, but the functionnalities are limited
Ok here is my Question I slightly modified the code provided in the link below
http://developer.android.com/reference/org/xmlpull/v1/XmlPullParser.html
I did the following :
import java.io.IOException;
import java.io.StringReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class xmlPParser
{
public String texte;
public xmlPParser (String arg)
throws XmlPullParserException, IOException
{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput( new StringReader ( arg ) );
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
{
//if(eventType == XmlPullParser.START_DOCUMENT) { System.out.println("Start document");}
// else if(eventType == XmlPullParser.START_TAG) { System.out.println("Start tag "+xpp.getName()); }
//else if(eventType == XmlPullParser.END_TAG) { System.out.println("End tag "+xpp.getName()); }
if(eventType == XmlPullParser.TEXT){ texte = xpp.getText(); } //{ System.out.println("Text "+xpp.getText());}
eventType = xpp.next();
}
//System.out.println("End document");
}
public String getTexte()
{
String returnTexte = texte;
return returnTexte;
}
}
In another java file, I can call the parser in the following way :
public xmlPParser myxpp;
...
myxpp = new xmlPParser("<foo>Hi five !!</foo>");
On that last line : I would like to be able to ask the parser to go to a file, instead of passing a string to it. how would i do that ?
I am not sure how to make use of this posting
Does getResources().getXml() supposes I am using the Android pullParser which I am not sure to be using now ?
XmlPullParser is not really a parser, it is an interface to a type of parser, called a "pull" parser.
The function getResources().getXml() returns an implementation of XmlPullParser for "parsing" XML resources. This is not a real XML parser -- in fact the original XML file was parsed at build time before being built into your app, and what this "XML parser" is doing is just returning the pre-digested XML structure as you call its API. This is the fastest "XML" parser available on Android (because it is not really parsing anything), but requires that the XML document be compiled as part of building your app.
The other implementation of XmlPullParser that you get from XmlPullParserFactory.newInstance() is not "limited" -- this implementation is full-featured, and can parse any raw XML document you give to it.
At least at one time (not sure if this is still the case), both the SAX parser and the parser returned by XmlPullParserFactory.newInstance() are actually built on the same underlying implementation, which is expat. The expat parser is a "push" parser (that is the same model as SAX), so the most efficient way to use it is with the SAX API. The XmlPullParser version has some more overhead from SAX since it needs to turn the underlying push semantics into a pull interface.
If it helps -- push means that it pushes the parsed data to you (callbacks you implement giving you each tag and other document element), while pull means you make calls to the parser to retrieve each element.

Categories

Resources