Given this XML
<dmodule>
<content>
<warningsAndCautionsRef>
<warningRef id="w001" warningIdentNumber="warning-001">
</warningRef>
<warningRef id="w002" warningIdentNumber="warning-002">
</warningRef>
<cautionRef id="c001" cautionIdentNumber="caution-001">
</cautionRef>
<cautionRef id="c002" cautionIdentNumber="caution-002">
</cautionRef>
</warningsAndCautionsRef>
<faultReporting>
<preliminaryRqmts>
<reqSafety>
<safetyRqmts cautionRefs="c001 c002" warningRefs="w001 w002"/>
</reqSafety>
</preliminaryRqmts>
</faultReporting>
</content>
</dmodule>
I would like to tokenize the attributes @cautionRefs
(and @warningRefs
) and then find the cautionRef
element that matches its @id
to the tokenized value:
<xsl:template match="@cautionRefs">
<xsl:for-each select="tokenize(.,'\s')">
<xsl:apply-templates select="//*[@id=.]"/>
</xsl:for-each>
</xsl:template>
but the apply-templates fails: Fatal error during transformation Leading '/' selects nothing: the context item is not a node. It works if I don't tokenize and use string functions instead but that is not desirable.
Desired result:
Tokenize @cautionRefs="c001 c002"
(which has multiple parent elements)
So each value is passed to the <cautionRef>
template that will retrieve the caution and warning statements, to be displayed in a PDF:
<xsl:apply-templates select="//*[@id='c001']"/>
<xsl:apply-templates select="//*[@id='c002']"/>
I tried using <xsl:key name="id" match="*" use="@id"/>
with
<xsl:for-each select="key('id',tokenize(.,'\s'))">
but the for-each
is blank.
The above apply-templates will match with this <cautionRef>
template, which retrieves the caution and warning statements correctly. I just need help with the context of the @cautionRefs
template:
<xsl:template match="cautionRef">
<xsl:variable name="IdentNumber" select="@cautionIdentNumber"/>
<xsl:apply-templates select="//cautionSpec[cautionIdent/@cautionIdentNumber=$IdentNumber]"/>
</xsl:template>
Here's a full working example. NB it's best to have this level of detail in the actual question; i.e. a sample input file, the XSLT, and output, along with an example of what you want the output to look like.
Input:
<test>
<safetyRqmts cautionRefs="c001 c002" warningRefs="w001"/>
<cautionRef id="c001" cautionIdentNumber="caution-001"/>
<cautionRef id="c002" cautionIdentNumber="caution-001"/>
</test>
Stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:template match="*|@*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:key name="by_id" match="*[@id]" use="@id"/>
<xsl:template match="@cautionRefs|@warningRefs">
<xsl:apply-templates select="key('by_id', tokenize(.))"/>
</xsl:template>
</xsl:stylesheet>
Output:
<test>
<safetyRqmts><cautionRef id="c001" cautionIdentNumber="caution-001"/><cautionRef id="c002" cautionIdentNumber="caution-001"/></safetyRqmts>
<cautionRef id="c001" cautionIdentNumber="caution-001"/>
<cautionRef id="c002" cautionIdentNumber="caution-001"/>
</test>