Plumbing XPointer

| 3 Comments | 1 TrackBack

I've implemented XPointer support (shorthand pointer, xmlns(), element() and xpath1() schemas) for the XInclude.NET project.
(Btw, I'm wondering if XPointer may be useful not only in XInclude context?)
It was really fun and good exercise. Here are some details:

Parsing. XPointer grammar is actually one of the simplest and can be easily parsed even by regexp, as Gudge has demonstrated in his implementation. But I'm not regexp fan, especially for parsing. (I'm lex/yacc fan for ages). Instead I decided to write custom lexer and parser, just as .NET guys did for XPath and C#. Lexer (aka scanner) scans the expression char by char, taking care about escaping and builds low-level lexemes (NCName, QName, Number etc). Parser then assembles those lexemes into a higher-level grammar constructs (PointerPart, SchemaName, SchemaData etc) according to the grammar and builds XPointer object model, aka compiled XPointer pointer, ready for evaluation.
It took me the whole day, but now I can agree to some degree with Peter Hallam, when he explained why they didn't use lex/yacc in C# compiler - sometimes it's really more fast and maintainable than lex/yacc based solution.

Evaluating. Well, I chose easy way and implemented XPointer evaluation using XmlDocument, just as Gudge did. It's so attractively easy. XPathDocument though should be a better candidate from many points of view: performace (it's more optimized for XPath evaluation), memory footprint (it's read-only) and data model conformance (there are subtle differences between underlying XmlDocument and XPathDocument data models, e.g. about adjacent text nodes - DOM allows them, but XPath data model doesn't). I'll consider to move to XPathDocument later, that would additionally require XmlReader wrapper around XPathNavigator, but fortunately Don has solved that problem already.

That's it. It looks quite powerful and seems to be working fine. E.g.

<xi:inlcude href="test2.xml#xmlns(foo=http://foo.com) 
                            xpath1(//foo:item[@name='bar']) 
                            element(items3/2)"/>

This includes all item elements in "http://foo.com" namespace, which have "bar" as name attribute's value or if such not found for some reason it includes second child element of the element with "items3" ID.

Now cleaning, commenting, documenting, testing and releasing.

Related Blog Posts

1 TrackBack

TrackBack URL: http://www.tkachenko.com/cgi-bin/mt-tb.cgi/34

Oleg writes about adding support for XPointer in XInclude.NET. I bet this would be very useful for us to re-use Read More

3 Comments

This sounds like something i need in puting wordML documents together, collecting different parts of the template (styles, header, tablestyles) from different documents and assembling.

I'm going to release it as beta this week. I'm curious, where and how do you plan to use it?

Cool! Any idea when you will be releasing this?

I could really use this feature in XInlcude.NET for a project I am working on.

adam...

Leave a comment