我正在尝试遍历一组节点,以构建一个具有不同排序值的菜单。所有可能的值都是已知的,但是在运行时不知道XML中包含了哪些值和多少值。已知的列表不时发生变化,因此,包括完整的列表将需要维护控制,我宁愿避免。
错误文本是必需的上下文项类型,父轴是节点();所提供的值具有项目类型xs:anyAtomicType。
我正在使用嵌入在Solr 7.6中的Xerces的XSLT2.0。
我想我理解为什么,因为我在上下文中是一个文本值,而不是一个节点,但我不知道如何绕过它。
这里有一个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>将引起行错误的XSL变换注释掉.
<?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>最后,对于不可用数据的占位符的结果.
<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发布于 2019-02-24 19:17:15
这个变量解决了你的问题,但是如果你只使用xsl:for-each-group,你就不会有它了。
<xsl:for-each-group select="doc" group-by="str[@name='type-abbrv']">
<xsl:sort select="current-grouping-key()"/>
<xsl:variable name="typeAbbrv" select="current-grouping-key()"/>
<xsl:variable name="typeName" select="str[@name='type-name']"/>
<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-group>当然可以缩短为
<xsl:for-each-group select="doc" group-by="str[@name='type-abbrv']">
<xsl:sort select="current-grouping-key()"/>
<xsl:call-template name="listElementUnknownList">
<xsl:with-param name="abbrv" select="current-grouping-key()"/>
<xsl:with-param name="name" select="concat(str[@name='type-name'], '-name')"/>
</xsl:call-template>
</xsl:for-each-group>所以我认为分组是你真正想要的,我试着把它的一部分实现为
<xsl:template match="result" mode="countUnknownList">
<dl>
<dt>Type (<xsl:value-of select="count(doc)" />)</dt>
<dd>
<ul>
<xsl:for-each-group select="doc" group-by="str[@name='type-abbrv']">
<xsl:sort select="current-grouping-key()"/>
<li>
<label>
<input id="{current-grouping-key()}"
type="checkbox"
checked="checked"
onclick="toggleRows('{current-grouping-key()}');"/>
<xsl:value-of select="concat(str[@name='type-name'], '(', count(current-group()), ')')"/>
</label>
</li>
</xsl:for-each-group>
</ul>
</dd>
<dt>System (<xsl:value-of select="count(doc)" />)</dt>
<dd>
<ul>
<xsl:for-each-group select="doc" group-by="str[@name='system-name']">
<xsl:sort select="current-grouping-key()"/>
<li>
<label>
<input id="{current-grouping-key()}"
type="checkbox"
checked="checked"
onclick="toggleRows('{current-grouping-key()}');"/>
<xsl:value-of select="concat(current-grouping-key(), '(', count(current-group()), ')')"/>
</label>
</li>
</xsl:for-each-group>
</ul>
</dd>
</dl>
</xsl:template>在https://xsltfiddle.liberty-development.net/gWvjQf4,您的示例的结果只有一个列表
<ul>
<li><label><input id="DSG" type="checkbox" checked onclick="toggleRows('DSG');">Design Drawing(3)</label></li>
<li><label><input id="DWG" type="checkbox" checked onclick="toggleRows('DWG');">Drawing(1)</label></li>
<li><label><input id="FLM" type="checkbox" checked onclick="toggleRows('FLM');">Flavor(3)</label></li>
<li><label><input id="PFP" type="checkbox" checked onclick="toggleRows('PFP');">Prefabricated(2)</label></li>
<li><label><input id="PXS" type="checkbox" checked onclick="toggleRows('PXS');">Production Assembly(3)</label></li>
<li><label><input id="REF" type="checkbox" checked onclick="toggleRows('REF');">Reference(4)</label></li>
<li><label><input id="STK" type="checkbox" checked onclick="toggleRows('STK');">Stack(2)</label></li>
<li><label><input id="SUB" type="checkbox" checked onclick="toggleRows('SUB');">Subsystem(1)</label></li>
</ul>第二个
<ul>
<li><label><input id="AB-4" type="checkbox" checked onclick="toggleRows('AB-4');">AB-4(2)</label></li>
<li><label><input id="AC-8" type="checkbox" checked onclick="toggleRows('AC-8');">AC-8(1)</label></li>
<li><label><input id="AC-9" type="checkbox" checked onclick="toggleRows('AC-9');">AC-9(12)</label></li>
</ul>希望我已经掌握了原始代码的意图。
发布于 2019-02-21 17:51:14
避免这种情况的一种方法是定义一个包含整个文档的顶级变量,如在this answer中。
...
<xsl:output method="html" indent="yes"/>
<xsl:variable name="mainDoc" select="/" />
...然后在注释掉的变量中引用它(我还更改了count中的谓词以计数所需的节点):
第一个
<xsl:variable name="quantity" select="count($mainDoc/response/result/doc/str[@name='type-abbrv' and text()=$abbrv])"/>第二个
<xsl:variable name="typeName" select="($mainDoc//doc[str[@name='type-abbrv']/text()=$typeAbbrv]/str[@name='type-name'])[1]" />https://stackoverflow.com/questions/54811433
复制相似问题