0

我有一个 XSLT 应用程序,它读取 Microsoft Word 2007/2010 压缩 XML 的内部格式,并使用 XSLT 将其转换为 HTML5。我正在研究如何添加选择性阅读 OpenOffice 文档而不是 MSWord 的功能。

Microsoft 将脚注文本的 XML 与文档文本的 XML 分开存储,这恰好适合我,因为我希望将脚注放在输出 HTML 页面末尾的块中。

然而,对我来说不幸的是,OpenOffice 将每个脚注放在其引用旁边,与文档文本内联。这是一个简单的段落示例:

  <text:p text:style-name="Standard">The real breakthrough in aerial mapping 
    during World War II was trimetrogon
    <text:note text:id="ftn0" text:note-class="footnote">
      <text:note-citation>1</text:note-citation>
      <text:note-body>
        <text:p text:style-name="Footnote">Three separate cameras took three
          photographs at once, a direct downward and an oblique on each side.</text:p>
      </text:note-body>
    </text:note>
    photography, but the camera was large and heavy, so there were problems finding
    the right aircraft to carry it.
  </text:p>

我的问题是,XSLT 是否可以正常处理 XML,但将每个 text:note 项保留到文档文本的末尾,然后一次全部发出?

4

3 回答 3

2

您认为您的逻辑是由输入中的事物顺序驱动的,但在 XSLT 中,您需要由输出中的事物顺序驱动。当您到达要输出脚注的位置时,请在输入中的任何位置查找脚注文本。诚然,这并不总是适用于明确输入驱动的应用模板递归下降处理模型。但是,这就是你必须这样做的方式。

于 2013-03-07T11:59:00.850 回答
1

您可以使用 <xsl:apply-templates mode="..."/>。我不确定确切的语法和您的用例,但也许下面的示例将为您提供有关如何解决问题的线索。

基本思想是两次处理你的节点。第一次迭代与现在几乎相同,第二次迭代只查找脚注并输出那些。您可以通过设置“模式”参数来区分这些迭代。

也许这个例子会给你一个线索如何解决你的问题。请注意,我在您的代码中使用了不同的标签,因此示例会更简单。

XSLT 表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="doc">
    <xml>
      <!-- First iteration - skip footnotes -->
      <doc>
        <xsl:apply-templates select="text" />
      </doc>

      <!-- Second iteration, extract all footnotes.
           'mode' = footnotes -->
      <footnotes>
        <xsl:apply-templates select="text" mode="footnotes" />
      </footnotes>
    </xml>
  </xsl:template>

  <!-- Note: no mode attribute -->
  <xsl:template match="text">
    <text>
      <xsl:for-each select="p">
        <p>
          <xsl:value-of select="text()" />
        </p>
      </xsl:for-each>
    </text>
  </xsl:template>

  <!-- Note: mode = footnotes -->
  <xsl:template match="text" mode="footnotes">
    <xsl:for-each select=".//footnote">
      <footnote>
        <xsl:value-of select="text()" />
      </footnote>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

输入 XML:

<?xml version="1.0" encoding="UTF-8"?>
<doc>
  <text>
    <p>
      some text
      <footnote>footnote1</footnote>
    </p>
    <p>
      other text
      <footnote>footnote2</footnote>
    </p>
  </text>
  <text>
    <p>
      some text2
      <footnote>footnote3</footnote>
    </p>
    <p>
      other text2
      <footnote>footnote4</footnote>
    </p>
  </text>
</doc>

输出 XML:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
  <!-- Output from first iteration -->
  <doc>
    <text>
      <p>some text</p>
      <p>other text</p>
    </text>
    <text>
      <p>some text2</p>
      <p>other text2</p>
    </text>
  </doc>

  <!-- Output from second iteration -->
  <footnotes>
    <footnote>footnote1</footnote>
    <footnote>footnote2</footnote>
    <footnote>footnote3</footnote>
    <footnote>footnote4</footnote>
  </footnotes>
</xml>
于 2013-03-07T11:37:46.840 回答
1

不要将其视为“持有”这些text:note项目,而是简单地在主通道中忽略它们,然后在最后用 a 收集它们并在//text:note那里处理它们,例如

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:text="whateveritshouldbe">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <!-- normal mode - replace text:note element by [reference] -->
  <xsl:template match="text:note">
    <xsl:value-of select="concat('[', text:note-citation, ']')" />
  </xsl:template>

  <xsl:template match="/">
    <document>
      <xsl:apply-templates select="*" />
      <footnotes>
        <xsl:apply-templates select="//text:note" mode="footnotes"/>
      </footnotes>
    </document>
  </xsl:template>

  <!-- special "footnotes" mode to de-activate the usual text:node template -->
  <xsl:template match="@*|node()" mode="footnotes">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" mode="footnotes" />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
于 2013-03-07T11:38:13.463 回答