Is SAX appropriate for this xml parsing in Android? - android

Provided a similar xml as follows,
<data>
<train>
<departing>
<schedule>
<time />
<time />
<time />
</schedule>
<locations>
<name>
<name/>
<name>
<name/>
</locations>
</departing>
</train>
<train>
<departing>
<schedule>
<time />
<time />
<time />
</schedule>
<locations>
<name>
<name/>
<name>
<name/>
</locations>
</departing>
</train>
</data>
For simplicity, I have omitted the attributes. The data I'm interested in is the following:
Attributes in every train element.
Elements within a particular train element.
In reality, this xml would be much longer(10+ times). Since this is for android, I want to choose the lightest way to parse this xml. DOM is not my option since it stores too many elements I don't need.
I have been thinking of using SAX. I would use boolean variable to skip unnecessary elements, but I still have to at least reach all of the train elements before I break out of parsing (by throwing exception).
Am I looking at the right approach with SAX for this?

I would first try the XPath option since that will solve your problem with the least amount of code.
I have no knowledge about the internal Android XPath implementation details, but if those turns out to be too heavy weight, I would look at the pull parser packages before submitting to SAX. Pull parsing is usually more straight forward to work with compared to SAX.

Related

Regex Structural Search Not Containing Word

I'm trying to search through my Android project's XML files for objects that do not contain a certain object.
My set of objects looks like this:
<View
android:id="#+id/obstacle3"
android:layout_width="#dimen/obstacle_width"
android:layout_height="#dimen/obstacle_width"
android:background="#drawable/play_portal"
android:layout_below="#+id/obstacle36"
android:layout_toRightOf="#+id/obstacle29"
ads:brother="#+id/obstacle21"
/>
<View
android:id="#+id/obstacle3"
android:layout_width="#dimen/obstacle_width"
android:layout_height="#dimen/obstacle_width"
android:background="#drawable/play_portal"
android:layout_below="#+id/obstacle36"
android:layout_toRightOf="#+id/obstacle29"
/>
<View
android:id="#+id/obstacle3"
android:layout_width="#dimen/obstacle_width"
android:layout_height="#dimen/obstacle_width"
android:background="#drawable/play_portal"
android:layout_below="#+id/obstacle36"
android:layout_toRightOf="#+id/obstacle29"
ads:brother="#+id/obstacle21"
/>
With this search,
<View(\s+[^>]*?)ads([^>]*?/>) I can find all Views that contain ads:brother attribute, but I want the inverse; I want to find all Views that do not contain ads:brother attribute.
I've tried numerous things to no avail. What am I doing wrong here?
__Insert mandatory disclaimer "don't parse xml with regex" here__
<View([^>](?!ads))*?\/>
See it in action
The idea is to check that after each matched character there is no ads following, thus there is no ads in the entire match.

is there a simple way to parse XML and find a needed element?

Usually when parsing XML i have to create all those lists with nodes, childs and what not.
Maybe there's a more simple way?...
For example I have a document that contains a few elements which id starts with "patch".
<rect id="patchW" x="48" display="none" fill="#993333" width="48" height="75"/>
And what I need is to make a list that would contain id ( of the elements that start with "patch" ), x and y ( if not present, then 0 ).
What do you think would be the best way of doing it?
Thanks!
Your best bet is SAX, which will fire events such as "start of element," "end of element," etc. Just listen to the start element events, and add the information you care about into a list every time you get an element whose ID starts with patch. Also, SAX is extremely fast - a lot of other XML parsing libraries, such as DOM, are built on top of SAX.
You should use a Parser such as JSOUP
Very simple to use and works tremendously well
you should use Xstream.It is useful.

Are there any StAX implementation for android?

I want to use StAX API implementation in android 1.6 and above devices. Are there any implementations out there ? I cannot use the jar file directly since it gives issues regarding inner class. If its not available, is there any way I can recompile the implementation ? Is there an alternate way for POJO class to be mapped into XML and vice versa directly, please exclude SAX parser and DOM parser.
I think it is possible for POJO class to be mapped into XML and vice versa using JAXB. But the situation is like this. Consider this example,
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cars>
<car registration="abc123">
<brand>BMW</brand>
<description>Sedan</description>
</car>
<car registration="abc123">
<brand>Ferrari</brand>
<description>SportsCar</description>
</car>
</cars>
Now in the result I want List which has the 2 cars in it.
Also how does JAXB parser fare against StAX ?
As far as I know, both Woodstox and Aalto should work on Android. Aalto is the single fastest conforming XML parser on Java platform, if that matters; and Woodstox supports widest range of XML constructs (from full DTD handling to RelaxNG/XML Schema validation).
For binding POJOs to XML, you could also consider Jackson extension jackson-xml-databind: while Jackson is mainly JSON processor, extension supports JAXB-style data binding for XML. And does it faster than JAXB reference implementation (see jvm-serializers benchmark).
This also should work on Android (Jackson itself is nr 1 JSON parser on Android).
So what you really want to "map POJOs into the XML and vice versa" is the Simple XML Library. You can use it with every version of Android from 1.5 up.
I even wrote a blog post explaining how to include it in one of your projects.

Grabbing XML File Data from a Website

Just wondering what would be the best way to grab the following data and parse it.
Here's an example of some the data I want to pull.
<?xml version="1.0" encoding="UTF-8" ?>
<eveapi version="2">
<currentTime>2010-11-19 19:23:44</currentTime>
<result>
<rowset name="characters" key="characterID" columns="name,characterID,corporationName,corporationID">
<row name="jennyhills" characterID="90052591" corporationName="Imperial Academy" corporationID="1000166" />
</rowset>
</result>
<cachedUntil>2010-11-19 20:20:44</cachedUntil>
</eveapi>
I've seen some examples on how to parse XML data but they are all based on if statements and that's a lot of hard coding is there a more generic way to do this?
Parsers are quite hardcoded that's the way they work. You can only check if a certain tag matches a certain pattern and then decide what to do. Especially for simple documents like yours that is absolutely no problem.
If you have more than one type of document to parse then I recommend reading this SO answer.
The "parsing", taking the term literally, is easy. Parsing is the process of taking a text string (in your case, from an http response) and turning it into a data structure such as an XML document tree. That process is handled for you by an XML parser, and you typically don't need to worry about it.
The part you're facing is how to query data from the parsed XML document, right? The easiest way to depends greatly on what you need to do with the data. But XPath is a good way to select data without a lot of verbose if statements and get-child function calls.
See also this question on using XPath in Android.

Abort SAX parsing mid-document?

I'm parsing a very simple XML schema with a SAX parser in Android.
An example file would be
<Lists>
<List name="foo">
<Note title="note 1" .../>
<Note title="note 2" .../>
</List>
<List name="bar">
<Note title="note 3" .../>
</List>
</Lists>
The ... represents more note data as attributes that aren't important to question.
I use a SAX parser to parse the document and only implement the startElement and 'endElement' methods of the HandlerBase to handle Note and List nodes.
However, In some cases the files can be very large and take some time to process. I'd like to be able to abort the parsing process at any time (i.e. user presses cancel button).
The best way I've come up with is to throw an exception from my startElement method when certain conditions are met (i.e. boolean stopParsing is true).
Is there a better way to do this?
I've always used DOM style parsers, so I don't fully understand the SAX parser.
One final note, I'm running this on Android, so I will have the Parser running on a worker thread to keep the UI responsive. If you know how I can kill the thread safely while the parser is running that would answer my question as well.
You might want to look into XMLPullParser as this could be performed easily by just not calling the next method. You are in more control over the parsing.
XmlPullParser xpp=getResources().getXml(R.xml.lists);
while (xpp.getEventType()!=XmlPullParser.END_DOCUMENT) {
if (xpp.getEventType()==XmlPullParser.START_TAG) {
if (xpp.getName().equals("list")) {
items.add(xpp.getAttributeValue(0));
}
}
xpp.next();
}

Categories

Resources