【发布时间】:2014-02-14 22:32:53
【问题描述】:
我想知道是否有人可以解释为什么某个特定的 XSL 模板没有达到预期的效果。我正在使用 XSL 2.0 (Saxon HE) 生成 XSL-FO。我想反转某些字体样式(例如,斜体段落中的斜体文本变为罗马文本)。 (在我的实际 XSL 中,我将此作为双通道过程的第二部分。无论如何都会出现问题,因此为了简单起见,我的示例显示了单通道。)
示例输入:
<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="skeleton">
<fo:region-body margin="1in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="skeleton">
<fo:flow flow-name="xsl-region-body">
<fo:block><fo:inline font-style="italic">A Title <fo:inline color="black" font-style="italic">With Some Roman Text</fo:inline> in the Middle</fo:inline></fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
XSL 示例:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//fo:inline[parent::*[@font-style=current()/@font-style]]/@font-style">
<xsl:message>Found nested font-style.</xsl:message>
<xsl:attribute name="font-style">normal</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
我想要的结果是:
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="skeleton">
<fo:region-body margin="1in" />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="skeleton">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:inline font-style="italic">
A Title
<fo:inline color="black" font-style="normal">
With Some Roman Text
</fo:inline>
in the Middle
</fo:inline>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
这是我使用这个在线测试仪得到的结果:http://chris.photobooks.com/xml/default.htm
当我使用 Saxon 运行此转换时,内部 fo:inline 仍然是斜体,并且我的调试消息永远不会出现。
我找到了一种使用 for-each 的解决方法(如果我不尝试选择属性,而是选择匹配的 fo:inline,则会触发模板)。但我很想知道这有什么问题,在我看来,更清洁的解决方案。
谢谢!
(只是为了添加更多信息,这是一个不太理想的模板,它确实可以让我得到我想要的结果,至少到目前为止:
<xsl:template match="//fo:inline[parent::*[@font-style=(current()/@font-style)]]">
<xsl:message>Found nested font-style.</xsl:message>
<xsl:copy>
<xsl:for-each select="@*">
<xsl:message><xsl:value-of select="local-name()"/></xsl:message>
<xsl:choose>
<xsl:when test="local-name()='font-style'">
<xsl:attribute name="font-style">normal</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
</xsl:copy>
【问题讨论】: