我正在构建一个非常复杂的XSLT,以便生成一些HTML标记。
一方面,我的目标是"延伸"使用某些模板生成的标记的class
属性。
不幸的是,它不起作用,因为XSLT标记<xsl:attribute>
只能设置&#34;属性。不要操纵现有的。
当我尝试时,擦除原始属性。
这是一个小型的复制品:
XML:
<node>
<item value="1" type="abc"/>
<item value="20" type="zxy"/>
</node>
XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="/node/item">
<p class="{@type}">
<xsl:call-template name='rule1' />
<xsl:call-template name='rule2' />
</p>
</xsl:template>
<xsl:template name='rule1'>
<xsl:attribute name='class'>
<xsl:choose>
<xsl:when test="@value mod 2 = 0">alpha</xsl:when>
<xsl:otherwise>omega</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
<xsl:template name='rule2'>
<xsl:attribute name='class'>
<xsl:choose>
<xsl:when test="@value mod 10 = 0">beta</xsl:when>
<xsl:otherwise>gamma</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
我想输出:
<?xml version="1.0" encoding="utf-8"?>
<p class="abc omega"/>
<p class="zxy beta alpha"/>
但它输出
<?xml version="1.0" encoding="utf-8"?>
<p class="omega"/>
<p class="beta"/>
是否可以保留原始属性,或在实用程序模板中检索它以重复使用它?
答案 0 :(得分:1)
似乎这个答案只能满足一个深刻的,非重复的课程。 在您要调用的模板的开头包含此内容:
<xsl:variable name="type" select="@type"/>
然后在更新属性值时,请尝试:
<xsl:attribute select="class">
<xsl:choose>
<xsl:when test="@value mod 2 = 0">
<xsl:value-of select="concat($type, ' alpha')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($type, ' omega')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
同样,我对XSLT并不是很满意,但我最近在测试中尝试了类似的东西,它起到了一定的作用。希望它有所帮助。
编辑:我不确定,但您可能必须将转义值放入&#34;空间&#34;在concat函数中,我忘了。答案 1 :(得分:0)
一个接近的解决方案可能是(感谢@aleski建议)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="/node/item">
<p>
<xsl:attribute name='class'>
<xsl:value-of select="@type" />
<xsl:call-template name='rule1' />
<xsl:call-template name='rule2' />
</xsl:attribute>
</p>
</xsl:template>
<xsl:template name='rule1'>
<xsl:choose>
<xsl:when test="@value mod 2 = 0"><xsl:value-of select="' alpha'" /></xsl:when>
<xsl:otherwise><xsl:value-of select="' omega'" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name='rule2'>
<xsl:choose>
<xsl:when test="@value mod 10 = 0"><xsl:value-of select="' beta'" /></xsl:when>
<xsl:otherwise><xsl:value-of select="' gamma'" /></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
你喜欢不起眼的编码解决方案吗?如果是这样,您可以重新编写解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/node/item">
<p class="{@type} {substring('alphaomega', 1 + 5 * (@value mod 2 = 0), 5)} {normalize-space(substring('beta gamma', 1 + 5 * (@value mod 10 = 0), 5))}">
</p>
</xsl:template>
</xsl:stylesheet>
因此,在一个属性中有三个属性值模板。如果你看看其中一个......
{substring('alphaomega', 1 + 5 * (@value mod 10 = 0), 5)}
这利用了&#34; true&#34;在数值表达式中求值为1,&#34; false&#34;求值为0.因此,当表达式为true时,将返回字符串的前五个字符。当它为假时,接下来的五个字符是。