xsl或xsl:fo格式化过程中两个模板的交互

问题描述 投票:1回答:1

在转换大型XML文本语料库(转换为PDF,XSL 3.0,XSL:FO)时,我遇到了一个模板问题,即控制最终出现在输出体中的内容以及由一个元素产生的边距中出现的内容。我不确定这是xsl还是xsl:fo问题。

问题在于<add type="margin_gloss">元素的输出,在下面的例子中由模板<xsl:template match="seg[@type='dep_event']">and和<xsl:template match="add[@type='margin_gloss']">处理。我希望<add type="margin_gloss">的内容只出现在边缘;但它也坚持在体内。

这个xml标记:

<corpus>
  <deposition>
    <text>
        <deposition-title>Some foo title</deposition-title>
        <seg type="dep_event"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam vitae venenatis
            ante. Suspendisse posuere velit non nisi tincidunt, commodo faucibus neque volutpat.
            Integer <add type="margin_gloss">This is a <foreign>foo</foreign> ma<supplied reason="added">rgin</supplied> note</add> 
            posuere laoreet sem eu scelerisque. Vestibulum purus risus, semper
            vitae suscipit non, mal<supplied reason="added">esuada</supplied> ut massa. Sed et auctor erat.</seg>
        <seg type="dep_event"> Suspendisse eu urna sed purus mattis placerat. Vestibulum <foreign>some English</foreign> scelerisque
            lectus, in lobortis tortor fa<supplied reason="added">cilisis</supplied> eu. Donec mollis pulvinar varius. Nam eget
            euismod ipsum, ac suscipit nunc. Sed volutpat non felis id varius. </seg>
    </text>
</deposition>
</corpus>

由xsl:fo处理:

<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fo="http://www.w3.org/1999/XSL/Format" 
xmlns:xd="http://www.pnp-software.com/XSLTdoc"
version="3.0">

<xsl:template match="/">
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master 
                master-name="page-recto"
                page-height="29.7cm"  page-width="21cm"
                margin-top="2cm" margin-bottom="2cm" 
                margin-left="2cm" margin-right="1cm">
                <fo:region-body 
                    region-name="xsl-region-body"/>
            </fo:simple-page-master>
        </fo:layout-master-set>

        <fo:page-sequence master-reference="page-recto">
            <fo:flow flow-name="xsl-region-body" 
                font-family="Times" font-weight="normal" 
                font-size="8pt" space-before="8pt" space-after="8pt"
                text-align="justify" end-indent="120pt">
                <xsl:apply-templates/>
            </fo:flow>
        </fo:page-sequence>

    </fo:root>
</xsl:template>

<xsl:template match="text">
    <fo:block 
        page-break-inside="avoid"
        font-size="9pt" font-weight="bold" 
        padding-bottom="1cm" end-indent="120pt">
        <xsl:apply-templates/>
    </fo:block>
</xsl:template>

<xsl:template match="seg[@type='dep_event']">
    <fo:block
        font-family="Times" font-weight="normal"
        font-size="8pt" space-before="8pt"
        space-after="8pt" text-align="justify"
        end-indent="2.5in">
        <xsl:if test=".//add[@type='margin_gloss']">
            <fo:float float="right">
                <fo:block-container width="2in" margin="10pt">
                    <fo:block font-size="7pt">
                            <xsl:apply-templates select=".//add[@type='margin_gloss']"/>
                    </fo:block>
                </fo:block-container>
            </fo:float>
        </xsl:if>
        <xsl:apply-templates/>
    </fo:block>
</xsl:template>

<xsl:template match="add[@type='margin_gloss']">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="foreign">
    <fo:inline font-style="italic">
        <xsl:apply-templates/>
    </fo:inline>
</xsl:template>

<xsl:template match="supplied[@reason='added']">
    <xsl:text>[</xsl:text><xsl:apply-templates/><xsl:text>]</xsl:text>
</xsl:template>


</xsl:stylesheet>

产生这个问题输出 - <add type="margin_gloss">的格式化内容(我用黄色突出显示)应该只出现在边距,而不是正文:

Yellow highlighted text should only appear in the margin, not the body

我尝试了各种形式的<apply-templates>,但是它们要么忽略/忽略边缘注释中的标记(例如:<xsl:apply-templates select="descendant::add[@type='margin_gloss']/text()"/>),要么完全消失边缘注释。

我应该注意到我正在使用xsl:fo处理器RenderX来完全支持<fo:float>

提前致谢。

xml xslt xsl-fo
1个回答
2
投票

问题是你的<add type="margin_gloss">被选中了两次。首先是这条线......

<xsl:apply-templates select=".//add[@type='margin_gloss']"/>

然后通过这条线......

<xsl:apply-templates/>

解决这个问题的一种方法是将显式xsl:apply-templates更改为此...

<xsl:for-each select=".//add[@type='margin_gloss']">
    <xsl:apply-templates />
</xsl:for-each>

然后,将匹配add[@type='margin_gloss']的模板更改为此,因为这将阻止xsl:apply-templates第二次处理它

<xsl:template match="add[@type='margin_gloss']" />

所以,两个相关的模板将如下所示....

<xsl:template match="seg[@type='dep_event']">
    <fo:block
        font-family="Times" font-weight="normal"
        font-size="8pt" space-before="8pt"
        space-after="8pt" text-align="justify"
        end-indent="2.5in">
        <xsl:if test=".//add[@type='margin_gloss']">
            <fo:float float="right">
                <fo:block-container width="2in" margin="10pt">
                    <fo:block font-size="7pt">
                        <xsl:for-each select=".//add[@type='margin_gloss']">
                            <xsl:apply-templates />
                        </xsl:for-each>
                    </fo:block>
                </fo:block-container>
            </fo:float>
        </xsl:if>
        <xsl:apply-templates/>
    </fo:block>
</xsl:template>

<xsl:template match="add[@type='margin_gloss']"/>
© www.soinside.com 2019 - 2024. All rights reserved.