I am attempting to loop through a set of nodes to build a menu of distinct, sorted values. All the possible values are known, but which and how many are included in the XML is not known at run time. The known list changes from time to time, so including the full list would require maintenance control I would rather avoid.
The error text is Required item type of the context item for the parent axis is node(); supplied value has item type xs:anyAtomicType.
I am using XSLT 2.0 from Xerces embedded in Solr 7.6.
I think I understand why, because I am contextually at a text value and not at a node, but I do not know a way around it.
Here is an example XML...
<?xml version="1.0" encoding="UTF-8"?>
<response>
<result name="response" numFound="25" start="0">
<doc>
<str name="id">REF-50102</str>
<str name="type-name">Reference</str>
<str name="type-abbrv">REF</str>
</doc>
<doc>
<str name="id">REF-50222</str>
<str name="type-name">Reference</str>
<str name="type-abbrv">REF</str>
</doc>
<doc>
<str name="id">REF-50245</str>
<str name="type-name">Reference</str>
<str name="type-abbrv">REF</str>
</doc>
<doc>
<str name="id">REF-50029</str>
<str name="type-name">Reference</str>
<str name="type-abbrv">REF</str>
</doc>
<doc>
<str name="id">SUB-4</str>
<str name="type-name">Subsystem</str>
<str name="type-abbrv">SUB</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">STK-80</str>
<str name="type-name">Stack</str>
<str name="type-abbrv">STK</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">STK-61</str>
<str name="type-name">Stack</str>
<str name="type-abbrv">STK</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">FLM-50025</str>
<str name="type-name">Flavor</str>
<str name="type-abbrv">FLM</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">FLM-50108</str>
<str name="type-name">Flavor</str>
<str name="type-abbrv">FLM</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">FLM-50109</str>
<str name="type-name">Flavor</str>
<str name="type-abbrv">FLM</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">PFP-50101</str>
<str name="type-name">Prefabricated</str>
<str name="type-abbrv">PFP</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">PFP-50103</str>
<str name="type-name">Prefabricated</str>
<str name="type-abbrv">PFP</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">DSG-50163</str>
<str name="type-name">Design Drawing</str>
<str name="type-abbrv">DSG</str>
<str name="system-name">AB-4</str>
</doc>
<doc>
<str name="id">DSG-50164</str>
<str name="type-name">Design Drawing</str>
<str name="type-abbrv">DSG</str>
<str name="system-name">AC-8</str>
</doc>
<doc>
<str name="id">DSG-50162</str>
<str name="type-name">Design Drawing</str>
<str name="type-abbrv">DSG</str>
<str name="system-name">AB-4</str>
</doc>
<doc>
<str name="id">PXS-81</str>
<str name="type-name">Production Assembly</str>
<str name="type-abbrv">PXS</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">PXS-83</str>
<str name="type-name">Production Assembly</str>
<str name="type-abbrv">PXS</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">PXS-82</str>
<str name="type-name">Production Assembly</str>
<str name="type-abbrv">PXS</str>
<str name="system-name">AC-9</str>
</doc>
<doc>
<str name="id">DWG-42</str>
<str name="type-name">Drawing</str>
<str name="type-abbrv">DWG</str>
<str name="system-name">AC-9</str>
</doc>
</result>
</response>
And the XSL transform with the errors causing lines are commented out...
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<!-- =========================================================================================== -->
<xsl:output method="html" indent="yes"/>
<!-- =========================================================================================== -->
<xsl:template match="/response">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<xsl:comment>Working if I know the list, but I do not.</xsl:comment>
<xsl:apply-templates select="result" mode="countKnownList"/>
<hr/>
<xsl:comment>Finds list dynamically, but can not get name or count.</xsl:comment>
<xsl:apply-templates select="result" mode="countUnknownList"/>
</body>
</html>
</xsl:template>
<!-- =========================================================================================== -->
<xsl:template name="listElementUnknownList">
<xsl:param name="abbrv"/>
<xsl:param name="name"/>
<!-- What I have tried unsuccessfully.
<xsl:variable name="quantity"><xsl:value-of select="count(//doc/str[@name='type-abbrv']/text()='$abbrv')"/></xsl:variable>
-->
<xsl:variable name="quantity">#</xsl:variable>
<li><label>
<xsl:element name="input">
<xsl:attribute name="id"><xsl:value-of select="$abbrv"/></xsl:attribute>
<xsl:attribute name="type">checkbox</xsl:attribute>
<xsl:attribute name="checked">true</xsl:attribute>
<xsl:attribute name="onclick">toggleRows('<xsl:value-of select="$abbrv"/>');</xsl:attribute>
</xsl:element><xsl:value-of select="$name"/>(<xsl:value-of select="$quantity" />)</label></li>
</xsl:template>
<!-- =========================================================================================== -->
<xsl:template match="result" mode="countUnknownList">
<dl>
<dt>Type (<xsl:value-of select="count(doc)" />)</dt>
<dd>
<ul>
<xsl:for-each select="distinct-values(doc/str[@name='type-abbrv'])">
<xsl:sort select="."/>
<xsl:variable name="typeAbbrv"><xsl:value-of select="."/></xsl:variable>
<!-- What I have tried unsuccessfully.
<xsl:variable name="typeName"><xsl:value-of select="../str[@name='type-name']"/></xsl:variable>
-->
<xsl:variable name="typeName"><xsl:value-of select="$typeAbbrv"/>-name</xsl:variable>
<xsl:call-template name="listElementUnknownList">
<xsl:with-param name="abbrv"><xsl:value-of select="$typeAbbrv"/></xsl:with-param>
<xsl:with-param name="name"><xsl:value-of select="$typeName"/></xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</ul>
</dd>
<dt>System (<xsl:value-of select="count(doc)" />)</dt>
<dd>
<ul>
<xsl:for-each select="distinct-values(doc/str[@name='system-name']/text())">
<xsl:sort select="."/>
<xsl:variable name="sysName"><xsl:value-of select="."/></xsl:variable>
<xsl:call-template name="listElementUnknownList">
<xsl:with-param name="abbrv"><xsl:value-of select="$sysName"/></xsl:with-param>
<xsl:with-param name="name"><xsl:value-of select="$sysName"/></xsl:with-param>
</xsl:call-template>
</xsl:for-each>
<xsl:call-template name="listElementUnknownList">
<xsl:with-param name="abbrv">None</xsl:with-param>
<xsl:with-param name="name">None</xsl:with-param>
</xsl:call-template>
</ul>
</dd>
</dl>
</xsl:template>
<!-- =========================================================================================== -->
<xsl:template name="listElementKnownList">
<xsl:param name="abbrv"/>
<xsl:param name="name"/>
<xsl:param name="quantity"/>
<li><label>
<xsl:element name="input">
<xsl:attribute name="id"><xsl:value-of select="$abbrv"/></xsl:attribute>
<xsl:attribute name="type">checkbox</xsl:attribute>
<xsl:attribute name="checked">true</xsl:attribute>
<xsl:attribute name="onclick">toggleRows('<xsl:value-of select="$abbrv"/>');</xsl:attribute>
</xsl:element><xsl:value-of select="$name"/>(<xsl:value-of select="$quantity" />)</label></li>
</xsl:template>
<!-- =========================================================================================== -->
<xsl:template match="result" mode="countKnownList">
<dl>
<dt>Type (<xsl:value-of select="count(doc)" />)</dt>
<dd>
<ul>
<xsl:call-template name="listElementKnownList">
<xsl:with-param name="abbrv">DSG</xsl:with-param>
<xsl:with-param name="name">Design Drawing</xsl:with-param>
<xsl:with-param name="quantity"><xsl:value-of select="count(doc[str[@name='type-abbrv']/text()='DSG'])"/></xsl:with-param>
</xsl:call-template>
<xsl:call-template name="listElementKnownList">
<xsl:with-param name="abbrv">FLM</xsl:with-param>
<xsl:with-param name="name">Flavor</xsl:with-param>
<xsl:with-param name="quantity"><xsl:value-of select="count(doc[str[@name='type-abbrv']/text()='FLM'])"/></xsl:with-param>
</xsl:call-template>
<xsl:call-template name="listElementKnownList">
<xsl:with-param name="abbrv">STK</xsl:with-param>
<xsl:with-param name="name">Stack</xsl:with-param>
<xsl:with-param name="quantity"><xsl:value-of select="count(doc[str[@name='type-abbrv']/text()='STK'])"/></xsl:with-param>
</xsl:call-template>
<!-- etc -->
</ul>
</dd>
</dl>
</xsl:template>
<!-- =========================================================================================== -->
</xsl:stylesheet>
And finally, the result with the placeholders for unavailable data...
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<!--Working if I know the list, but I do not.-->
<dl>
<dt>Type (19)</dt>
<dd>
<ul>
<li><label><input id="DSG" type="checkbox" checked="true" onclick="toggleRows('DSG');">Design Drawing(3)</label></li>
<li><label><input id="FLM" type="checkbox" checked="true" onclick="toggleRows('FLM');">Flavor(3)</label></li>
<li><label><input id="STK" type="checkbox" checked="true" onclick="toggleRows('STK');">Stack(2)</label></li>
</ul>
</dd>
</dl>
<hr>
<!--Finds list dynamically, but can not get name or count.-->
<dl>
<dt>Type (19)</dt>
<dd>
<ul>
<li><label><input id="DSG" type="checkbox" checked="true" onclick="toggleRows('DSG');">DSG-name(#)</label></li>
<li><label><input id="DWG" type="checkbox" checked="true" onclick="toggleRows('DWG');">DWG-name(#)</label></li>
<li><label><input id="FLM" type="checkbox" checked="true" onclick="toggleRows('FLM');">FLM-name(#)</label></li>
<li><label><input id="PFP" type="checkbox" checked="true" onclick="toggleRows('PFP');">PFP-name(#)</label></li>
<li><label><input id="PXS" type="checkbox" checked="true" onclick="toggleRows('PXS');">PXS-name(#)</label></li>
<li><label><input id="REF" type="checkbox" checked="true" onclick="toggleRows('REF');">REF-name(#)</label></li>
<li><label><input id="STK" type="checkbox" checked="true" onclick="toggleRows('STK');">STK-name(#)</label></li>
<li><label><input id="SUB" type="checkbox" checked="true" onclick="toggleRows('SUB');">SUB-name(#)</label></li>
</ul>
</dd>
<dt>System (19)</dt>
<dd>
<ul>
<li><label><input id="AB-4" type="checkbox" checked="true" onclick="toggleRows('AB-4');">AB-4(#)</label></li>
<li><label><input id="AC-8" type="checkbox" checked="true" onclick="toggleRows('AC-8');">AC-8(#)</label></li>
<li><label><input id="AC-9" type="checkbox" checked="true" onclick="toggleRows('AC-9');">AC-9(#)</label></li>
<li><label><input id="None" type="checkbox" checked="true" onclick="toggleRows('None');">None(#)</label></li>
</ul>
</dd>
</dl>
</body>
</html