根据this SO问题,应该可以在match
的XPath表达式中使用参数。但是,如果要在同一模板中使用xsl:param
的{{1}},它似乎无效。
我的XML文件如下所示
xsl:template
和我的XSL文件一样。
<?xml version="1.0" encoding="UTF-8"?>
<myRoot>
<myNode myAttribute="3">
<myChildAttribute myChildAttribute="a" />
</myNode>
<myNode myAttribute="2">
<myChildAttribute myChildAttribute="b" />
</myNode>
<myNode myAttribute="1" />
</myRoot>
不幸的是,当使用SAXON 9HE运行时,它会以以下错误结束
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="myRoot">
<xsl:apply-templates select="myNode">
<xsl:sort select="@myAttribute" />
<xsl:with-param name="myParam" select="max(myNode/@myAttribute)" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="myNode[node() and @myAttribute = $myParam]">
<xsl:param name="myParam" />
<xsl:for-each select="myChildAttribute">
INSERT INTO a(b) VALUES ('<xsl:value-of select="@myChildAttribute" />');
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
是否无法在相同的模板的match-XPath表达式中使用模板的参数!?
答案 0 :(得分:3)
是否无法在模板中使用模板的参数 match-XPath表达同一个模板!?
不,当选择执行模板时,模板的匹配表达式中的任何变量/参数必须在范围内(已定义/可见)。
因为模板是XSLT指令(在全局级别定义),所以范围内(他们可以看到)的唯一变量/参数是全局级变量/参数。
只有在选择执行模板之后才会将模板的参数传递给它 - 而不是在此之前。这意味着在执行模板选择过程时,该参数的值不存在。
因此,如果要在执行过程的模板选择中使用非全局表达式,则需要在相应的select
指令的xsl:apply-templates
属性中提供该表达式,其中此表达式可以被评估 - 不在模板的match
属性中,无法评估此表达式。
为清楚起见,以下代码更正了所提供代码中的问题:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="myRoot">
<xsl:apply-templates select="myNode[@myAttribute = max(../myNode/@myAttribute)]">
<xsl:sort select="@myAttribute" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="myNode[node()]">
<xsl:for-each select="myChildAttribute">
INSERT INTO a(b) VALUES ('<xsl:value-of select="@myChildAttribute" />');
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<myRoot>
<myNode myAttribute="3">
<myChildAttribute myChildAttribute="a" />
</myNode>
<myNode myAttribute="2">
<myChildAttribute myChildAttribute="b" />
</myNode>
<myNode myAttribute="1" />
</myRoot>
没有产生错误,这是转换的输出(我不能说“正确的输出”,因为没有定义任何要求因此无法验证。我对此有所保留代码:例如,<xsl:sort>
的{{1}}子元素的使用没有意义,因为它将对相等(max())值进行排序,并且对相等值序列进行排序会产生相同的序列): / p>
xsl:apply-templates
答案 1 :(得分:2)
我认为这不会起作用。该参数在您定义的模板中有效。但是,匹配表达式实际上不是模板的一部分。当myParam尚未定义时,必须从外部进行评估。
您必须将max(myNode / @ myAttribute)的过滤移动到apply-templates call的select表达式。