温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - XSLT: recursive templates on parametrized nodes
xslt xslt-3.0

其他 - XSLT:参数化节点上的递归模板

发布于 2020-04-07 11:10:09

我想在参数化的节点类型列表上递归调用模板。

如果将这些参数化的值传递给模板,则不会递归。但是,如果我将值直接传递给模板,则递归将按预期工作。

如何在与参数化值匹配时使递归起作用?

(我使用的是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

查看更多

提问者
Richard
被浏览
33
Michael Kay 2020-02-03 18:43

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"/>

但是请注意,这仅在您匹配主源文档中的节点时才有效。