我想在参数化的节点类型列表上递归调用模板。
如果将这些参数化的值传递给模板,则不会递归。但是,如果我将值直接传递给模板,则递归将按预期工作。
如何在与参数化值匹配时使递归起作用?
(我使用的是Saxon版本9.9.1.6(家庭版)来应用XSLT转换)
输入HTML
<p>
<p>paragraph1</p>
<p>paragraph2</p>
<a>link here</a>
</p>
具有直接值的XSLT模板:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="container" select="p|a"/>
<xsl:template match="p|a">
Name: <xsl:value-of select="name()"/>
Value: <xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="UTF-8"?>
Name: p
Value:
Name: p
Value: paragraph1
Name: p
Value: paragraph2
Name: a
Value: link here
这是可行的,而且我期望会发生。但是,当我尝试将参数化的值传递给模板时,它匹配顶级元素,但不匹配任何子元素。
带有参数化值的XSLT模板:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="container" select="p|a"/>
<xsl:template match="$container">
Name: <xsl:value-of select="name()"/>
Value: <xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="UTF-8"?>
Name: p
Value:
paragraph1
paragraph2
link here
match="$variable"
是XSLT 3.0中的新语法,该语法与全局变量中保存的节点集中的节点匹配。该变量保存匹配的节点,而不是它们的名称。
另外,select =“ p | a”会选择文档上下文中的节点,这不是您想要的。用于select="'p|a'"
将变量设置为字符串。例如,它有助于使用as
属性。as="node()*"
或as="xs:string"
避免混淆变量实际应包含的内容。
要匹配名称,请使用 match="*[local-name()=tokenize($container, '\|')]"
或者,您可以定义一个静态参数和一个阴影属性:
<xsl:param name="container" select="'p|a'" static="yes"/>
<xsl:template _match="{$container}">...</xsl:template>
或者,如果愿意,可以将变量初始化为匹配节点的集合,如下所示:
<xsl:param name="matching-nodes" select="//p | //a"/>
然后使用匹配
<xsl:template match="$matching-nodes"/>
但是请注意,这仅在您匹配主源文档中的节点时才有效。
根据xsltfunctions.com/xsl/fn_tokenize.html,“ |” regex需要以反斜杠转义。通过这种更改,这对我有用。谢谢。