XSL child:: Selectors
I recently implemented a new method of adding plugins into pages in Spring - and inspired by Microformats, I decided to examine utilising existing xhtml tags to specify the plugin instead of creating our own XML tags.
Previously we inserted XML within the page content with a custom plugin:
<div class="plugin">
<feed category="all" format="blog.listing" table="pages" limit="10"/>
</div>
Now using our xhtml method, we simply add a <select> form element with the built in editor controls:
<p><select name="feed">
<option value="limit">10</option>
<option value="format">blog.listing</option>
</select></p>
This raises a bit of a problem however. The editor correctly wraps the <select> tag in a block element - a <p> tag. However when we rewrite the <select> element (which basically replaces the <select> tag with the results of a query) - we end up with invalid xhtml due to the additional (and superfluous) <p> tags surrounding the inserted results.
<p><div>
<p>Results Here</p>
</div>
</p>
Since the editor is actually producing correct code - and our existing xsl template rewriting is causing the problem, we needed to solve the problem in the xsl template.
So how to strip out the <p> tag?Matching on the <select> tag, then applying the template to it's parent (the <p> tag) was not yeilding the correct results - however by simply using a child:: selector the whole process is quite trivial:
<xsl:template match="p[child::select/@name='feed']">
<xsl:apply-templates select="./*" />
</xsl:template>
<xsl:template match="select[@name='feed']">
<!-- Rewrite 'select' tag -->
</xsl:template>
The code above simply says "modify the p element which contains a select element with the name feed". The 'apply-templates' xsl, then applies rewriting to the contents of the <p> element (which in this case is the <select> tag).
Because we have not actually rewritten or defined a replacement for the <p> element itself - it effectively is stripped out completely and replaced with the results of the apply-templates.
Perfect!