The best way to test whether a node is a w:xyz node is
test="self::w:xyz"
This is especially true when using namespaces, as the form
name()='w:xyz'
tests the namespace prefix rather than the URI.
I don't know what you were thinking of with
x/y/@name() = 'w:p'
This suggests you ought to do some reading, it looks as if you've been trying to find out the rules of the language by inspired guesswork (not unusual, I'm afraid, but with XPath not very productive).
As for the recursion, I would recommend doing a "sibling recursion" here. The general logic is:
<xsl:template match="*" mode="recurse">
do something
<xsl:apply-templates select="following-sibling::*[1]" mode="recurse"/>
</xsl:template>
and of course you fire the thing off by applying templates to the first child.
In this case rather than having an xsl:choose within the template to switch on element type, why not have one rule per element type:
<xsl:template match="w:tbl" mode="recurse">
<xsl:text>table found</xsl:text>
<xsl:apply-templates select="following-sibling::*[1]" mode="recurse"/>
However, I may have misunderstood your requirement, because I can't see anything in this example that needs sibling recursion rather than a conventional depth-first apply-templates from a parent to all the children. You need sibling recursion when the processing of one child depends on information gleaned when processing its preceding siblings and passed on as a parameter.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference