OK, after a bit of experimenting (with a closer look at hints in previous posts), I've been able to get the xp:include working dynamically.
I used the technique of passing parameters along with the xPage address.
As an example, bringing up the "menu" page with an included page of "test1" can be done with "/menu.xsp?Page=test1.xsp".
If I want a different page embedded, I simply load the page "/menu.xsp?Page=test2.xsp".
The xp:include "pageName" attribute is calculated from the "Page" parameter passed to the webpage via a 'context.getUrlParameter("Page")' call.
Simple when you know how....
I've tied this to a menu tree on the left hand side of a xPage to allow navigation of various views/forms by clicking items in the tree.
The overall frame of the xPage only needs doing once with the tree navigation, headers, footers, etc. and then each view/form is embedded when the item is clicked. This keeps the real working pages quite small and leaves the surrounding frame separate and consistent across all pages.