我有以下xml:
<group>
<cont cont-type="author">
<name>abc</name>
</cont>
<cont cont-type="editor">
<name>cba</name>
</cont>
</group>
我希望能够根据参数选择编辑或作者,以便我可以调用正确的模板,例如:
<xsl:if test="$cont_type='editor'">
<xsl:call-template name="editors"/>
</xsl:if>
所以我希望能够在名为编辑器的模板中选择with cont_type = editor,我将如何选择节点的路径?
这是我的编辑模板:
<xsl:template name="editors">
<xsl:if test="exists(cont[@cont-type='editor'])">
<xsl:apply-templates select="cont[@cont-type='editor']"/>
</xsl:if>
</xsl:template>
问题在于此编辑器模板,我无法访问 cont 元素,因为它的路径未指定,并且在我的文档中,我有多个具有不同路径的 组 元素。
答案 0 :(得分:0)
这个XSLT是否接近您的需求?
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="text()" />
<xsl:template match="/group">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="cont[@cont-type='author']">
<xsl:call-template name="authors"/>
</xsl:template>
<xsl:template match="cont[@cont-type='editor']">
<xsl:call-template name="editors"/>
</xsl:template>
</xsl:stylesheet>
此代码在相应的匹配项上调用名为authors
或editors
的模板。
很遗憾,您无法将cont-type
的值直接传递给xsl:call-template
,因为在XSLT-1.0中,其select=""
属性需要QName。
因此,例如,以下是不可能的:
<xsl:template match="cont[@cont-type='editor' or @cont-type='author']">
<xsl:call-template name="{concat(@cont-type,'s')}"/>
</xsl:template>
如果您想根据通过XSLT处理器传递给xsl:stylesheet
的参数来自定义输出,则必须在根级别定义xsl:param
,在这种情况下名为JSPparam
。考虑所有xsl:choose
,决定调用哪个模板由xsl:when test="$JSPparam=..."
决定。
我将xsl:call-template
中的XPath包含在xsl:with-param
中且参数为what
。因此,XPath在xsl:param name="what" />
的相应模板中收到,可以使用$
前缀进行访问以供进一步使用(我使用xsl:copy-of
进行说明)。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:param name="JSPparam" select="''" />
<xsl:template match="text()" />
<xsl:template match="/group">
<xsl:choose>
<xsl:when test="$JSPparam = 'author'">
<xsl:call-template name="authors">
<xsl:with-param name="what" select="cont[@cont-type = 'author']" />
</xsl:call-template>
</xsl:when>
<xsl:when test="$JSPparam = 'editor'">
<xsl:call-template name="editors">
<xsl:with-param name="what" select="cont[@cont-type = 'editor']" />
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="authors">
<xsl:param name="what" />
<xsl:copy-of select="$what" />
</xsl:template>
<xsl:template name="editors">
<xsl:param name="what" />
<xsl:copy-of select="$what" />
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
就这么简单:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pType" select="'author'"/>
<xsl:template match="/*">
<xsl:apply-templates select="group/cont[@cont-type = $pType]"/>
</xsl:template>
<xsl:template match="cont">
<xsl:element name="{@cont-type}">
<xsl:copy-of select="node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML片段(由单个顶部元素包围以使其成为格式良好的XML文档):
<groups>
<group>
<cont cont-type="author">
<name>abc</name>
</cont>
<cont cont-type="editor">
<name>cba</name>
</cont>
</group>
<group>
<cont cont-type="author">
<name>def</name>
</cont>
</group>
</groups>
想要的操作(匹配group/cont[@cont-type = $pType]
的模板并执行他们应该做的任何事情)执行,导致这种情况:
<author>
<name>abc</name>
</author>
<author>
<name>def</name>
</author>
如果我们将全局参数 $pType
的定义修改为:
<xsl:param name="pType" select="'editor'"/>
然后我们再次获得预期的正确结果:
<editor>
<name>cba</name>
</editor>
请注意:
在&#34;真实情况&#34;你最有可能有两个不同的模板:
<xsl:template match="cont[@cont-type = 'author']">
. . . . .
</xsl:template>
和
<xsl:template match="cont[@cont-type = 'editor']">
. . . . .
</xsl:template>