我正在寻找将参数传递给模板匹配的解决方法。我知道这在XPath中是不允许的,因此我正在寻找一个'计划B'解决方案。
这是我希望的工作:
xslt(2.0)的第1部分:
<xsl:template match="/">
<xsl:for-each select="//Main/PageList/Page">
<xsl:result-document href="{@ID}.xml">
<Page ID="{@ID}">
<xsl:apply-templates select="node()">
<xsl:with-param name="theID" select="@ID"/>
</xsl:apply-templates>
</Page>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
如此相当简单,不要理会使用的标签,它本质上是通过一个节点,并为每个节点创建一个XML文件。每个节点都以一个ID开头,我想为其他模板提供这个ID。不幸的是,这适用于命名模板,但它不适用于匹配的模板(如果我至少正确理解了理论)
以下是我希望看到的工作:
<!-- identity template -->
<xsl:template match="node()|@*">
<xsl:param name="theID"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="theID" select="$theID"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<!-- lots of templates here doing what I want them to do -->
<!-- one template creating an issue -->
<xsl:template match="@src">
<!-- would be nice to know the current ID, but unfortunately this one stays empty... -->
<xsl:param name="theID"/>
<!-- clean current attribute a bit -->
<xsl:variable name="S1" select="replace(.,'\.\.\/','')"/>
<xsl:attribute name="src">
<xsl:choose>
<xsl:when test="contains($S1,'common')">
<!-- just use current value, don't bother about current ID -->
<xsl:value-of select="$S1"/>
</xsl:when>
<xsl:otherwise>
<!-- use ID parameter -->
<xsl:value-of select="concat($theID,'_',$S1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
不要看这样的代码,它只是整个文件的一小部分,但实质是我想在另一个模板中使用我的第一部分(match =“/”)中的ID参数(match =“@ src”),但这似乎相当复杂。
我错过了什么吗?如果我运气不好而且确实不可能,那么有人会建议我如何继续吗?
提前致谢!
答案 0 :(得分:1)
您的问题在这里:
<xsl:apply-templates select="node()">
<xsl:with-param name="theID" select="@ID"/>
</xsl:apply-templates>
select
属性指定处理应该在当前节点的任何子节点上继续。
但是node()
只选择子节点(元素,文本节点,处理说明和注释) - 而不是属性。
<强>解决方案强>:
-
<xsl:apply-templates select="@*">
<xsl:with-param name="theID" select="@ID"/>
</xsl:apply-templates>
0.2。 为了仅处理当前节点的src
属性的处理:
-
<xsl:apply-templates select="@src">
<xsl:with-param name="theID" select="@ID"/>
</xsl:apply-templates>
0.3。为了间接处理当前节点后代的属性,请执行:
-
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="theID" select="@ID"/>
</xsl:apply-templates>
您还必须确保处理node()
的任何模板必须具有名为xsl:param
的{{1}},并且必须在任何theID
指令中传递此参数< /强>
在实践中,这意味着您将覆盖所有XSLT内置模板,因为他们不了解您的xsl:apply-templates
。
答案 1 :(得分:0)
我认为不是
<xsl:apply-templates select="node()">
<xsl:with-param name="theID" select="@ID"/>
</xsl:apply-templates>
你想要
<xsl:apply-templates select="node()">
<xsl:with-param name="theID" select="parent::Page/@ID"/>
</xsl:apply-templates>
假设您要传递父ID
元素的Page
属性。
另一方面,select="node()"
选择任何子节点,如子元素,子注释节点,子文本节点,子处理指令节点,所以我不明白为什么你以后显示匹配属性节点的模板