UPDATE: This post was updated on May 29th 2013 to reflect changes to simplify the SelectExpandClause API between 5.5 beta and 5.5 RTM Release, the biggest change involved merging Select and Expand into SelectedItems.
The ODataUriParser is continuing its march towards completion. In fact in ODataLib version 5.5 (RTM drops on May 29th) it is almost complete.
In the last post I talked about how you could parse $filter and $orderby. In 5.5 you can also parse $select, $expand and the path part of an OData url too. Which means all that remains it putting all these bits together into a method that will parse the whole Url with a single step.
That said with 5.5 you can do this yourself, the algorithm is essentially:
If you do this you can build a structure that holds the whole URI converted into various ASTs. In 5.6 we will add a new Parse(..) method that will do this for you and return an appropriate data structure to hold the ODataPath and various query clauses.
In the meantime lets take a look what we’ve added in 5.5:
This API is pretty simple, you need an ODataUriParser (which requires an IEdmModel and a base Uri) then you call ParsePath(..), like this:
// Get a model, clearly you could do this in many ways, in this example we borrow one of the sample OData models IEdmModel model = EdmxReader.Parse(XmlTextReader.Create(“http://services.odata.org/V3/OData/OData.svc/$metadata”));
// Construct a parser for that model ODataUriParser parser = new ODataUriParser(model, new Uri(“http://server/service”)); // Parse a relative path ODataPath path = parser.ParsePath(new Uri("http://services.odata.org/V3/OData/OData.svc/Products/ODataDemo.FeaturedProduct(1)/Advertisement"));
If you do this you get an ODataPath that hold an enumeration of segments. In this case the segments will be (from first to last):
There are of course other segments OData paths you will encounter other segments like: PropertySegment, BatchSegment, MetadataSegment, ValueSegment, CountSegment, NavigationPropertyLinkSegment, OperationSegment and so forth.
Those of you using WebAPI will be aware that it has it’s own code for parsing the path part of an OData URI. This is basically just bad timing, if we’d finished the ODataLib URI parser sooner Web API would have used it to parse paths as well. Indeed going forward Web API is likely to refactor their ODataPath code so that it uses the new ODataLib path parsing capabilities.
The $select and $expand clauses are related, for example $select effects what is expanded. So we have a single method for parsing both simultaneously, this allows us to create an AST that captures the semantics of both query options together.
For example if someone issued a query like this:
You would convert this into an AST by making the following calls:
// Construct a parser for that model ODataUriParser parser = new ODataUriParser(model, new Uri(“http://server/service”));
// Parse the $select and $expand clauses SelectExpandClause selectAndExpand = parser.ParseSelectAndExpand("ID,Name,Category", "Category", type, set);
The SelectExpandClause is a data structure that looks like this:
The new version of the ODataUriParser that ships in ODataLib version 5.5 is finished. 5.5 adds support for parsing Paths, $select and $expand, which means the ODataUriParser now handles all of OData. All that remains is to add a more convenient way of parsing a full Url in one step, and we will ship something that does that in version 5.6. In the meantime you can still parse an OData Uri completely if you use the algorithm outlined above.
If you have any questions, concerns or suggestion, as always we are keen to hear from you.