一段时间以来,我一直在使用这个xsl:key。我无法达到期望的输出,而且我也不知道哪里出了错。
以下是xml(XSLT视为xml)的示例:
<xsl:template mode="something" match="node">
<xsl:variable name="node" select="."/>
<xsl:variable name="example" select="example"/>
<xsl:variable name="example" select="normalize-space(.)"/>
<xsl:if test="not($node//*[matches(local-name(),$example)])">
<xsl:call-template name="name">
<xsl:with-param name="rule" select="'S140'"/>
<xsl:with-param name="other" select="'textValue'"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template mode="other" match="node">
<xsl:call-template name="name">
<xsl:with-param name="rule" select="'S150'"/>
<xsl:with-param name="other" select="'textValue'"/>
</xsl:call-template>
</xsl:template>
<xsl:template mode="another" match="anotherNode">
<xsl:choose>
<xsl:when test="something">
<xsl:variable name="example" select="path"/>
<xsl:call-template name="name">
<xsl:with-param name="name" select="'S140'"/>
<xsl:with-param name="content" select="$example"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="path0">
<xsl:variable name="example"
select="path1"/>
<xsl:call-template name="name">
<xsl:with-param name="name" select="'S145'"/>
<xsl:with-param name="content" select="$example"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="path2">
<xsl:variable name="ele"
select="path3"/>
<xsl:call-template name="name">
<xsl:with-param name="name" select="'S150'"/>
<xsl:with-param name="content" select="$example"/>
</xsl:call-template>
</xsl:when>
</xsl:template>
和我从中读取值的外部XML。
<VALIDATION>
<VALIDATION_STATE ATTR="S140">a</VALIDATION_STATE>
<VALIDATION_STATE ATTR="S150">b</VALIDATION_STATE>
<VALIDATION_STATE ATTR="S155">c</VALIDATION_STATE>
</VALIDATION>
和我的XSLT:
<xsl:key name="xslRuleCode" match="xsl:call-template[@name = 'name']" use="substring(xsl:with-param[1]/@select,2,4)"/>
<xsl:param name="validation" select="document('validation.xml')"/>
<xsl:template match="xsl:template">
<xsl:variable name="xslRule" select="key('xslRuleCode', .)"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
<xs:annotation>
<xs:documentation>Documentation</xs:documentation>
<attr_id>
<xsl:value-of select="concat('URL', $xslRule)"/>
</attr_id>
<description>
<xsl:for-each select="$validation/VALIDATION/VALIDATION_STATE">
<xsl:if test="@ATTR= $xslRule">
<xsl:value-of select="node()"/>
</xsl:if>
</xsl:for-each>
</description>
</xs:annotation>
</xsl:template>
在XML文件中(以XSLT格式)有两个值,另一个在外部XML文件中。
我们的想法是接触这两个元素,将它们进行比较,如果匹配,则将元素的值写入相关注释中。
预期输出为:
<xsl:template mode="something" match="node">
<xsl:variable name="node" select="."/>
<xsl:variable name="example" select="example"/>
<xsl:variable name="example" select="normalize-space(.)"/>
<xsl:if test="not($node//*[matches(local-name(),$example)])">
<xsl:call-template name="name">
<xsl:with-param name="rule" select="'S140'"/>
<xsl:with-param name="other" select="'textValue'"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xs:annotation>
<xs:documentation>Documentation</xs:documentation>
<attr_id>
URL/S140
</attr_id>
<description>
a
</description>
<xsl:template mode="other" match="node">
<xsl:call-template name="name">
<xsl:with-param name="rule" select="'S150'"/>
<xsl:with-param name="other" select="'textValue'"/>
</xsl:call-template>
</xsl:template>
<xs:annotation>
<xs:documentation>Documentation</xs:documentation>
<attr_id>
URL/S150
</attr_id>
<description>
b
</description>
另一项编辑:
如果我与<xsl:call-template>
匹配而不是在<xsl:template>
中匹配
我能够达到我想要的价值。但是我不想在调用模板之后创建注释,它必须在每个模板之后。
<xsl:template match="xsl:call-template[@name = 'name']">
<xsl:param name="xslRule" select="substring(xsl:with-param[1]/@select, 2, 4)"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
<xsl:choose>
<xsl:when test="ancestor::xsl:template/last()">
<xs:annotation>
<xs:documentation>documentation</xs:documentation>
<rule_id>
<xsl:value-of select="concat('URL', $xslRule)"/>
</rule_id>
<description>
<xsl:for-each select="$validation/VALIDATION/VALIDATION_STATE">
<xsl:if test="@ATTR= $xslRule">
<xsl:value-of select="node()"/>
</xsl:if>
</xsl:for-each>
</description>
</xs:annotation>
</xsl:when>
</xsl:choose>
</xsl:template>
答案 0 :(得分:1)
我认为您不需要在这里使用xsl:key
。仅当您匹配命名模板并想要获得所有xsl:call-templates
称为它的东西时,您才需要这样做。
我认为只需执行此操作即可解决您的问题...
<xsl:variable name="xslRule"
select="substring((.//xsl:call-template/xsl:with-param[@name='rule'])[1]/@select, 2, 4)"/>
这假设每个模板中只有一个xsl:call-template
。
编辑:如果模板中有多个xsl:call-template
语句,并且想要在主模板本身之后为每个语句添加注释,则可以使用xsl:for-each
。
<xsl:template match="xsl:template">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
<xsl:for-each select=".//xsl:call-template/xsl:with-param[1]/@select">
<xsl:variable name="xslRule" select="." />
<xs:annotation>
<xs:documentation>Documentation</xs:documentation>
<attr_id>
<xsl:value-of select="concat('URL', $xslRule)"/>
</attr_id>
<description>
<xsl:for-each select="$validation/VALIDATION/VALIDATION_STATE">
<xsl:if test="@ATTR= $xslRule">
<xsl:value-of select="node()"/>
</xsl:if>
</xsl:for-each>
</description>
</xs:annotation>
</xsl:for-each>
</xsl:template>