I like this approach. I find XPath a powerful, simple language and use it often for parsing XML. The idea of using XPath to process tree structures that aren't stored natively as XML interests me.
I wonder if writing your own match() method to implement XPath-like syntax is the best approach, though. Rather than effectively writing another XPath parser, why not serialise your data tree to XML, process it with an existing parser such as XML::LibXML or XML::XPath, then convert the XML back into your initial tree format? That would be slower, but would allow you to reuse existing modules.
The speed issue may be significant for you, but this approach might help other monks with similar problems.