注意:您将问题标记为 XSLT 2.0,但 Umbraco 不使用 XSLT 2.0,它(目前)卡在 XSLT 1.0 上。
$option1= '' or $option1=umbraco.library:GetPreValueAsString(./option1)
您的错误可能有多种原因。处理器不需要从左到右或从右到左处理 or 表达式,甚至允许始终计算两个表达式,即使第一个表达式为真(这与按位运算符 (无序)在其他语言中,而这些语言中的布尔运算符(有序)通常使用早期突破)。
另一个错误可能是上下文节点中的选项值不为空,也不是整数或空,在这种情况下,您的代码将始终返回错误。
你可以通过测试./optionX来扩展你的表达式,但是你仍然有评估顺序的问题。
也就是说,您如何解决它并防止出现错误?在 XSLT 1.0 中,这有点笨拙(即,您不能定义函数,也不能使用序列),但这里有一种方法:
<xsl:variable name="pre-default-option">
<default>1</default>
<default>2</default>
<default>3</default>
<default>4</default>
</xsl:variable>
<xsl:variable name="default-option"
select="exslt:node-set($pre-default-option)" />
<xsl:variable name="pre-selected-option">
<option><xsl:value-of select="$option1" /></option>
<option><xsl:value-of select="$option2" /></option>
<option><xsl:value-of select="$option3" /></option>
<option><xsl:value-of select="$option4" /></option>
</xsl:variable>
<xsl:variable name="selected-option" select="exslt:node-set($pre-selected-option)" />
<xsl:variable name="pre-process-nodes">
<xsl:variable name="selection">
<xsl:apply-templates
select="umbraco.library:GetXmlNodeById(1098)/*"
mode="pre">
<xsl:with-param name="opt-no" select="1" />
</xsl:apply-templates>
</xsl:variable>
<!-- your original code uses 'and', so is only true if all
conditions are met, hence there must be four found nodes,
otherwise it is false (i.e., this node set will be empty) -->
<xsl:if test="count($selection) = 4">
<xsl:copy-of select="$selection" />
</xsl:if>
</xsl:variable>
<!-- your original variable, should now contain correct set, no errors -->
<xsl:variable name="nodes" select="exslt:node-set($pre-process-nodes)"/>
<xsl:template match="*[@isDoc and string(umbracoNaviHide) != '1']" mode="pre">
<xsl:param name="opt-no" />
<xsl:variable name="option"
select="$selected-option[. = string($opt-no)]" />
<!-- gets the child node 'option1', 'option2' etc -->
<xsl:variable
name="pre-ctx-option"
select="*[local-name() = concat('option', $opt-no)]" />
<xsl:variable name="ctx-option">
<xsl:choose>
<!-- empty option param always allowed -->
<xsl:when test="$option = ''">
<xsl:value-of select="$option"/>
</xsl:when>
<!-- if NaN or 0, this will return false -->
<xsl:when test="number($pre-ctx-option)">
<xsl:value-of select="$default-option[$opt-no]"/>
</xsl:when>
<!-- valid number (though you could add a range check as well) -->
<xsl:otherwise>
<xsl:value-of select="umbraco.library:GetPreValueAsString($pre-ctx-option)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- prevent eternal recursion -->
<xsl:if test="4 >= $opt-no">
<xsl:apply-templates select="self::*" mode="pre">
<xsl:with-param name="opt-no" select="$opt-no + 1" />
</xsl:apply-templates>
<!-- the predicate is now ctx-independent and just true/false
this copies nothing if the conditions are not met -->
<xsl:copy-of select="self::*[$option = $ctx-option]" />
</xsl:if>
</xsl:template>
<xsl:template match="*" mode="pre" />
注(1):上面的代码是我手写的,只测试了语法错误,我无法测试它,因为你没有提供一个输入文档来测试它。如果您发现错误,请务必编辑我的回复以使其正确。
注(2):上面的代码概括了使用编号参数的工作。通过概括它,代码变得有点复杂,但它变得更容易维护和扩展,并且更不容易出现复制/粘贴错误。