com.codename1.processing.package.html Maven / Gradle / Ivy
XPath based expression language designed to assist in JSON/XML parsing/generating
The {@link com.codename1.processing.Result} class provides a subset of
XPath, but it is not limited to just XML
documents, it can also work with JSON documents, and even with raw {@link java.util.Map} objects.
As an example, we'll demonstrate how to process a response from the
Google Reverse Geocoder API.
Lets start with this XML snippet:
We want to extract some of the data above into simpler string results. We can do this using:
If you are at all familiar with processing responses from webservices, you will notice that what would
normally require several lines of code of selecting and testing nodes in regular java can now be
done in a single line using the new path expressions.
In the code above, input can be any of:
- {@link java.lang.InputStream} directly from {@link com.codename1.io.ConnectionRequest#readResponse(java.io.InputStream)}
- XML or JSON document in the form of a {@code String}
- XML DOM {@link com.codename1.xml.Element} returned from {@link com.codename1.xml.XMLParser}
- JSON DOM {@link java.util.Map} returned from {@link com.codename1.io.JSONParser}
To use the expression processor when calling a webservice, you could use something like the following to
parse JSON (notice this is interchangeable between JSON and XML):
The returned JSON looks something like this (notice it's snipped because the data is too long):
The XML processor currently handles global selections by using a double slash anywhere within the
expression, for example:
NOTE: Notice that Google's JSON webservice uses plural form for each of
the node names in that API (ie. results, address_components, and types) where they don't in the XML services
(ie result, address_component etc.).
Example 2
It also possible to do some more complex expressions. We'll use the following XML fragment for the next batch of examples:
Above, if you want to select the IDs of all players that are ranked in the top 2, you can use an
expression like:
(Notice above that the expression is using an attribute for selecting both rank and id. In JSON
documents, if you attempt to select an attribute, it will look for a child node under the attribute name you ask for).
If a document is ordered, you might want to select nodes by their position, for example:
It is also possible to select parent nodes, by using the ?..' expression. For example:
Above, we globally find a lastname element with a value of ?Hewitt', then grab the parent node of
lastname which happens to be the player node, then grab the id attribute from the player node.
Alternatively, you could get the same result from the following simpler statement:
It is also possible to nest expressions, for example:
In the above example, if the player node had an address object, we'd be selecting all players from Canada.
This is a simple example of a nested expression, but they can get much more complex, which will be
required as the documents themselves get more complex.
Moving on, to select a node based
on the existence of an attribute:
Above, we selected the IDs of all ranked players. Conversely, we can select the non-ranked players like this:
(Logical not (!) operators currently are not implemented).
You can also select by the existence
of a child node.
Above, we selected all players that have a middle name.
Keep in mind that the Codename One path expression language is not a full implementation of
XPath 1.0, but does already handle many of the most useful features of the specification.