首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用XSL确定(伪)二进制属性的状态

使用XSL确定(伪)二进制属性的状态
EN

Stack Overflow用户
提问于 2014-11-26 17:23:22
回答 1查看 118关注 0票数 1

今天早上,我正在为xhtml 标记实现xsl格式。通常,你希望引文被斜体化:

代码语言:javascript
复制
<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)中可以找到第一个,有点天真的尝试来解决这个问题:

代码语言:javascript
复制
<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输出中)。我想要解决的难题是,你如何才能确定是否有任何特定的引文应该被斜体化?

我第一次尝试解决这个问题:

代码语言:javascript
复制
<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>

当然,很明显,这并不是在每种情况下都有效:

代码语言:javascript
复制
<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>

上面的模板会将引用的字体样式设置为正常,因为这个条件是第一个满足的条件:

代码语言:javascript
复制
<xsl:when test="ancestor::*[@font-style='italic']">

我曾想过

代码语言:javascript
复制
test="count(ancestor::*[@font-style='italic']) - count(ancestor::*[@font-style='normal') mod 2 = 0"

但这也不起作用,因为标签的顺序很重要;也就是说,这样做是完全合法的:

代码语言:javascript
复制
<div font-style="italic> ... <p font-style="italic"> ...</p></div>

我知道如何用一种过程语言来实现这一点:通过祖先列表向后计数,递增/递减一个“斜体”计数变量,但考虑到变量是不可变的,我想不出用XSL做这件事的任何方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-26 18:26:11

听起来,您实际上只需要知道包含@font-style的第一个祖先是否具有@font-styleitalic。您可以使用经过修改的模板对树进行回退,直到找到具有@font-style的祖先为止。

例如..。

代码语言:javascript
复制
<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中执行此操作的方法。

代码语言:javascript
复制
<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>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27155283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档