今天早上,我正在为xhtml 标记实现xsl格式。通常,你希望引文被斜体化:
<xsl:template match="cite">
<fo:inline font-style="italic"><xsl:apply-templates/></fo:inline>
</xsl:template>当然,这是一个复杂的问题:如果周围的文本已经被斜体化,那么为了对比的目的,您希望引用字体样式是正常的。在Doug的IBM教程(http://www.ibm.com/developerworks/library/x-xslfo2app/#cite)中可以找到第一个,有点天真的尝试来解决这个问题:
<xsl:template match="cite">
<xsl:choose>
<xsl:when test="parent::i">
<fo:inline font-style="normal">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:when>
<xsl:otherwise>
<fo:inline font-style="italic">
<xsl:apply-templates select="*|text()"/>
</fo:inline>
</xsl:otherwise>
</xsl:choose>
</xsl:template>这是可以的,但xsl-fo允许在任何块或内联标记中使用字体样式属性。因此,假设在某种程度上修改了html的风格,字体样式属性可以出现在任何(xhtml严格)块或内联标记中,这些块或内联标记可以包含包含文本的文本或子标记(除了出现在xsl-fo输出中)。我想要解决的难题是,你如何才能确定是否有任何特定的引文应该被斜体化?
我第一次尝试解决这个问题:
<xsl:template match="cite">
<fo:inline>
<xsl:choose>
<xsl:when test="ancestor::i">
<xsl:variable name="font-style" select="'normal'"/>
</xsl:when>
<xsl:when test="parent::*[@font-style='italic']">
<xsl:variable name="font-style" select="'normal'"/>
</xsl:when>
<xsl:when test="parent::*[@font-style='normal']">
<xsl:variable name="font-style" select="'italic'"/>
</xsl:when>
<xsl:when test="ancestor::*[@font-style='italic']">
<xsl:variable name="font-style" select="'normal'"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="font-style" select="'italic'"/>
</xsl:otherwise>
<xsl:attribute font-style=$font-style/>
<xsl:apply-templates/>
</fo:inline>
</xsl:template>当然,很明显,这并不是在每种情况下都有效:
<div font-style="italic">
<p font-style="normal">Old, but good science fiction, such as
<b><cite>Stephenson, Neil "Snowcrash"</cite></b>
more text....
</p></div>上面的模板会将引用的字体样式设置为正常,因为这个条件是第一个满足的条件:
<xsl:when test="ancestor::*[@font-style='italic']">我曾想过
test="count(ancestor::*[@font-style='italic']) - count(ancestor::*[@font-style='normal') mod 2 = 0"但这也不起作用,因为标签的顺序很重要;也就是说,这样做是完全合法的:
<div font-style="italic> ... <p font-style="italic"> ...</p></div>我知道如何用一种过程语言来实现这一点:通过祖先列表向后计数,递增/递减一个“斜体”计数变量,但考虑到变量是不可变的,我想不出用XSL做这件事的任何方法。
发布于 2014-11-26 18:26:11
听起来,您实际上只需要知道包含@font-style的第一个祖先是否具有@font-style值italic。您可以使用经过修改的模板对树进行回退,直到找到具有@font-style的祖先为止。
例如..。
<xsl:template match="cite">
<xsl:variable name="isItalic" as="xs:boolean">
<xsl:choose>
<xsl:when test="not(ancestor::*[@font-style[string()]])">
<xsl:sequence select="false()"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="isItalic"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:inline font-style="{if ($isItalic) then 'normal' else 'italic'}">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<xsl:template match="*" mode="isItalic" as="xs:boolean">
<xsl:choose>
<xsl:when test="parent::*[@font-style[string()]]">
<xsl:sequence select="if (parent::*/@font-style='italic') then
true() else false()"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select=".." mode="isItalic"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>这里有另一种在XSLT1.0中执行此操作的方法。
<xsl:template match="cite">
<xsl:variable name="font-style">
<xsl:choose>
<xsl:when test="not(ancestor::*[@font-style[string()]])">
<xsl:text>italic</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="." mode="getFontStyle"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<fo:inline font-style="{$font-style}">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<xsl:template match="*" mode="getFontStyle">
<xsl:choose>
<xsl:when test="parent::*[@font-style[string()]]/@font-style='italic'">
<xsl:text>normal</xsl:text>
</xsl:when>
<xsl:when test="parent::*[@font-style[string()]]">
<xsl:text>italic</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select=".." mode="getFontStyle"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>https://stackoverflow.com/questions/27155283
复制相似问题