Creating an xsl key by combining elements
<t> <rendition xml:id="b">color: blue</rendition> <rendition xml:id="r">color: red</rendition> <tagUsage gi="p" render="b" /> <tagUsage gi="emph" render="r" /> </t> How can I create an XSL 1.0 key in @gi-based rendition elements in a tagUsage element by attaching rendition / @ xml: id to tagUsage / @ render? Sort of
<xsl:key name="rendition-by-tagName" match="rendition" use="//tagUsage[@xml:id of rendition = @render of tagUsage]/@gi" /> so that for a given "p" the key will return a blue rendition ; "emph", the key will return a red rendition .
Using
<xsl:key name="kRendByUsageGi" match="rendition" use="../tagUsage[@render=current()/@xml:id]/@gi"/> Here is a complete check :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:key name="kRendByUsageGi" match="rendition" use="../tagUsage[@render=current()/@xml:id]/@gi"/> <xsl:template match="/"> <xsl:copy-of select="key('kRendByUsageGi', 'p')/text()"/> ======== <xsl:copy-of select="key('kRendByUsageGi', 'emph')/text()"/> </xsl:template> </xsl:stylesheet> When this conversion is applied to the provided XML document :
<t> <rendition xml:id="b">color: blue</rendition> <rendition xml:id="r">color: red</rendition> <tagUsage gi="p" render="b" /> <tagUsage gi="emph" render="r" /> </t> the desired, correct result is output:
color: blue ======== color: red I found that the following using the second key () works with xsltproc, so if this is your target processor, this should help. However, he does not work with Saxon.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:key name='kTagUsage' match='tagUsage' use='@render'/> <xsl:key name="kRendByUsageGi" match="rendition" use="key('kTagUsage', @xml:id)/@gi"/> <xsl:template match="/"> <xsl:copy-of select="key('kRendByUsageGi', 'p')/text()"/> ======== <xsl:copy-of select="key('kRendByUsageGi', 'emph')/text()"/> </xsl:template> </xsl:stylesheet>