我在模板中有一系列相互依赖的param元素(即每个后续param使用前一个param的值作为它的一部分< XPath)
e.g。
<xsl:param name="input1" select="path/node/@value"/>
<xsl:param name="input2" select="path/anothernode[@value=$input1]/anothervalue"/>
<xsl:param name="input3" select="path/thirdnode[@value=$input2]/@endvalue"/>
等。等
一堆参数在一次运行中完美运行。但是,当我使用for-each循环调用模板并使用xsl:with-param将for-each值传递给它时,只处理顶部参数 - 该值不会传递给下一个参数。
这是我的完整xsl:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/" name="test">
<xsl:param name="memberId"
select="PLMXML/Organisation/UserData/UserValue/UserList/Item/@value"/>
<xsl:param name="memberRef"
select="PLMXML/OrganisationMember[@id=$memberId]/@memberRef"/>
<xsl:param name="memberRef2"
select="translate($memberRef,'#','')"/>
<xsl:param name="userId"
select="PLMXML/User[@id=$memberRef2]/@personRef"/>
<xsl:param name="userId2"
select="translate($userId,'#','')"/>
<xsl:param name="personName"
select="PLMXML/Person[@id=$userId2]/@lastName"/>
<xsl:param name="groupRef"
select="PLMXML/User[@id=$memberRef2]/UserData/UserValue/@dataRef"/>
<xsl:param name="groupRef2"
select="translate($groupRef,'#','')"/>
<xsl:param name="groupName"
select="PLMXML/Organisation[@id=$groupRef2]/@name"/>
<xsl:param name="roleRef"
select="PLMXML/Organisation[@id=$groupRef2]/UserData/UserValue/@dataRef"/>
<xsl:param name="roleRef2"
select="translate($roleRef,'#','')"/>
<xsl:param name="roleName"
select="PLMXML/Role[@id=$roleRef2]/@name"/>
<xsl:value-of select="$memberId"/>
<xsl:value-of select="$memberRef"/>
<xsl:value-of select="$personName"/>
<xsl:value-of select="$groupName"/>
<xsl:value-of select="$roleName"/>
</xsl:template>
<xsl:template match="/">
<xsl:for-each select="PLMXML/Organisation/UserData/UserValue/UserList/Item/@value">
<xsl:call-template name="test">
<xsl:with-param name="memberId" select="."/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
但是,for-each循环只在模板中填充堆栈的顶部变量&#39; test&#39; - 即xsl:value-of select="$memberId"/>
有效,但<xsl:value-of select="$memberRef"/>
没有。
非常感谢有关如何解决此问题的任何想法。
答案 0 :(得分:1)
你遇到的问题是上下文之一;您当前在XML中的位置。考虑一下 xsl:for-each 循环
<xsl:for-each select="PLMXML/Organisation/UserData/UserValue/UserList/Item/@value">
您正在循环 @value 属性,这意味着您在循环中位于 @value 属性上,因此任何相对xpath表达式都将相对于该属性。当您执行 xsl:call-template 时,您仍将位于 @value 属性上,因此 xsl:param中的所有xpath表达式陈述将与此相关。
<xsl:param name="memberRef"
select="PLMXML/OrganisationMember[@id=$memberId]/@memberRef"/>
也就是说, select 语句正在当前 @value 下面寻找 PLMXML 元素,这显然不存在!
第一个参数 memberId 的作用原因是您将显式值传递给它,因此将使用选择中的默认值属性。所有其他参数都不起作用,因为它们将使用默认值。
解决方案可能是使所有参数都具有绝对表达式,这意味着为它们添加/
前缀。
<xsl:param name="memberRef"
select="/PLMXML/OrganisationMember[@id=$memberId]/@memberRef"/>
/
表示顶级文档节点,因此xpath表达式将相对于该节点,而不是当前节点。
注意,您可以考虑在此实例中使用 xsl:key 来查找此类元素。例如
<xsl:key name="OrganisationMember" match="OrganisationMember" use="@id" />
然后param语句变为:
<xsl:param name="memberRef" select="key('OrganisationMember', $memberId)/@memberRef"/>
顺便说一句,将两个具有相同优先级的模板匹配相同的东西被视为错误。所以,你的第一个名字&#39;模板应该删除匹配属性。即代替<xsl:template match="/" name="test">
,执行此操作
<xsl:template name="test">