XSLT(在TEI中编号嵌套的div)

时间:2015-12-16 10:04:46

标签: xml xslt xpath

我正在使用TEI Simple,并希望在标题和TOC行中添加编号。我了解如何构建它但无法在书的各个部分(frontbodyback)达到预期的结果。它总是在根目录重新启动。我的两个级别的代码(其余的我做同样的事):

<xsl:template match="tei:div[@n='1']/tei:head" mode="toc">
  <fo:block font-size="12pt">
    <xsl:number format="1. " count="tei:div[@n='1']" level="multiple"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="tei:div[@n='2']/tei:head" mode="toc">
  <fo:block font-size="12pt">
    <xsl:number format="1.1. " count="tei:div[@n='1']|tei:div[@n='2']" level="multiple"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

显然,我用n属性标记任何div。我将模板应用于文件的整个text部分。结果如下:

[Front]
1. First
  1.1. First of First
[Body]
1. Second

精确的XPath是:

TEI/text/front/div[@n="1"]/head
TEI/text/body/div[@n="1"]/head
TEI/text/back/div[@n="1"]/head

......而且,显然:

TEI/text/front/div[@n="1"]/div[@n="2"]/head
TEI/text/body/div[@n="1"]/div[@n="2"]/head
TEI/text/back/div[@n="1"]/div[@n="2"]/head

更新

我决定采用更严格的书籍结构。通常,对前后物质进行编号并不常见。现在我正在使用它并且它正常工作(我想可以将所有主要部分的所有内容混合在一起但这种方式对我来说更合理。我将它用于8个级别。)然而,我想知道是否有这是另一种更聪明的做法。随着级别的提高,代码看起来有点笨拙。

<xsl:template match="tei:div[@n='1']/tei:head[ancestor::tei:front and ancestor::tei:back]" mode="toc">
  <xsl:variable name="level" select="count(ancestor-or-self::tei:div)"/>
  <fo:inline>
    <xsl:apply-templates/>
  </fo:inline>
</xsl:template>

<xsl:template match="tei:div[@n='1']/tei:head[ancestor::tei:body]" mode="toc">
  <xsl:variable name="level" select="count(ancestor-or-self::tei:div)"/>
  <fo:inline>
    <xsl:number format="1. " count="tei:div[@n='1'][ancestor::tei:body]" level="multiple"/>
    <xsl:apply-templates/>
  </fo:inline>
</xsl:template>

<xsl:template match="tei:div[@n='2']/tei:head[ancestor::tei:body]" mode="toc">
  <xsl:variable name="level" select="count(ancestor-or-self::tei:div)"/>
  <fo:inline>
    <xsl:number format="1.1. " count="tei:div[@n='1'][ancestor::tei:body]|tei:div[@n='2'][ancestor::tei:    body]" level="multiple"/>
    <xsl:apply-templates/>
  </fo:inline>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

如果您使用例如,这是一个简短的样本。

<xsl:template match="tei:div[@n='1']/tei:head" mode="toc">
  <fo:block font-size="12pt">
    <xsl:number format="1. " value="count(preceding::div[@n = 1]) + 1"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

您应该将主号码设为1.2.。对于次要编号,我不确定您是否需要跨不同部分的序列,或者是否要将计数限制为每个部分,对于第一个选项使用例如。

<xsl:template match="tei:div[@n='2']/tei:head" mode="toc">
  <fo:block font-size="12pt">
    <xsl:number format="1.1 " value="count(preceding::div[@n = 1]) + 1, count(preceding::div[@n = 2]) + 1"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

代表第二个

<xsl:template match="tei:div[@n='2']/tei:head" mode="toc">
  <fo:block font-size="12pt">
    <xsl:number format="1.1 " value="count(preceding::div[@n = 1]) + 1, count(preceding-sibling::div[@n = 2]) + 1"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

未经测试但应该给你一个想法。

另一种方法是使用level="any生成主号码,使用level="single"生成第二个号码。