我对 XSLT 很陌生,一直在努力实现递归模板,该模板通过多个文本节点并搜索匹配项。创建递归模板时,我收到一条错误消息,指出"'/'的第一个操作数的必需项类型是 node((;提供的值具有项目类型 xs:string"。我不知道如何选择多个节点作为节点,而不是字符串。
目标:我有多个测试节点,例如
<Chain>1 3 4 7 20 50 72 ...</Chain>
我想遍历这些节点以查找匹配的数字。找到这个数字后,我需要选择父元素属性的子字符串。
以下是带有递归模板的样式表的一部分:
<xsl:template match="/l:LandXML/h:HexagonLandXML/h:Point/h:PointCode">
<xsl:variable name="id2" select="../@uniqueID"/>
<xsl:call-template name="tests">
<xsl:with-param name="input" select="/l:LandXML/h:HexagonLandXML/h:PlanFeature/h:CoordGeom/h:Spline/h:Chain"/>
<xsl:with-param name="id" select="$id2"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="tests">
<xsl:param name="id"/>
<xsl:param name="input"/>
<xsl:choose>
<xsl:when test="substring-before($input, ' ') = $id">
<xsl:value-of select="format-number(substring-before(substring-after($input/../@oID, '_'), '_'), '#')"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="tests">
<xsl:with-param name="input" select="substring-after($input, ' ')"/>
<xsl:with-param name="id" select="$id"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
为了更好地理解,完整的XML和XSLT在这里:https://xsltfiddle.liberty-development.net/94hvTzd/17
提前感谢任何帮助。
所以你想知道是否
<Chain>1 3 4 7 20 50 72 ...</Chain>
包含,比如说,50
?
这里不需要递归模板。XPath字符串函数可以很好地做到这一点。对于 XPath 1.0,请使用
//Chain[contains(concat(' ', ., ' '), concat(' ', $val, ' '))]
$val
在哪里'50'
.concat()
确保没有部分匹配项,并且找到开头和结尾的匹配项。
对于 XPath 2.0 及更高版本,您可以使用tokenize()
。
//Chain[tokenize(., ' ') = $val]
您的模板在<xsl:with-param name="input" select="substring-after($input, ' ')"/>
传递字符串值,字符串值没有父节点,因此您必须将原始元素存储/传递为单独的参数。请注意,xsltfiddle 可以访问(并且正在使用它(Saxon 9.8 HE,一个 XSLT 3 处理器,在那里你可以通过使用例如tokenize(Chain, ' ')[. = $id]
或类似。