如何最好地组合XSLT处理文档?

时间:2015-05-08 20:43:51

标签: xslt xslt-1.0 xsl-fo

我有一堆报告,可以单独编辑和转换(xml - > xsl-fo)来创建pdf文件。另外,我想将所有报告合并到一本书中,使用单一转换创建。我以为我可以使用 document()函数:

(个别报告如下):

<?xml version="1.0"?>
<!DOCTYPE blue_book SYSTEM "../DTD/blue_book.dtd">
<blue_book>

  ~~stuff~~

</blue_book>

我创建了一个名为reports.xml的占位符文件:

<?xml version="1.0"?>
<reports>
  <report filename="title.xml"/>
  <report filename="preface.xml"/>
  <report filename="report1.xml"/>
  <report filename="report2.xml"/>
  <report filename="report3.xml"/>
  <report filename="report4.xml"/>
</reports>

然后在我的样式表中使用类似的东西来表达它们:

<xsl:for-each select="/reports/report">
  <xsl:apply-templates select="document(@filename)/blue_book"/>
</xsl:for-each>

这种作品,但我创建的所有用于开始页面编号和基于文档中的位置自动生成id以用于链接目的的代码都是分开的。例如,我希望页面编号从第3个报告开始。如果我只将所有xml文件合并到一个文件中,以下工作正常。

<xsl:template match="blue_book">
  <xsl:choose>
    <xsl:when test="count(preceding-sibling::blue_book) &lt; 2">
      <fo:page-sequence master-reference="front-matter">
        <fo:flow flow-name="xsl-region-body">
          <xsl:apply-templates/>
        </fo:flow>
      </fo:page-sequence>
    </xsl:when>

    <xsl:when test="count(preceding-sibling::blue_book) = 2">
      <fo:page-sequence master-reference="report">
        <xsl:attribute name="initial-page-number">1</xsl:attribute>

        <fo:static-content flow-name="first-xsl-region-before">
            <xsl:if test="lead_para">
              <fo:block font-variant="small-caps" text-align="center">
                <xsl:value-of select="lead_para"/></fo:block>
            </xsl:if>
          <fo:block>&#x00A0;</fo:block>
        </fo:static-content>
(etc. -- lots of xsl-fo)

但是当使用 document()函数加载文件时,似乎前一个兄弟计数始终为0;即它只查看该特定报告而不考虑之前加载的报告。

这是有道理的,但并不能解决我的问题。有没有标准的方法来做到这一点?特别是,我希望处理所有报告,就像它们在同一个XML文档中一样,但不必将它们实际物理连接在一起。*

*如果有人想知道为什么,那是因为编辑们想要单独维护和编辑报告,但仍然可以通过AH Formatter运行一些东西,这样就可以得到完整的书。文件的连接超出了他们的技能。

2 个答案:

答案 0 :(得分:2)

为什么不使用实体?只需更改创建占位符文件的方式即可。你问:

&#34;特别是,我希望处理所有报告,就像它们在同一个XML文档中一样,但不必将它们实际物理连接在一起。&#34;

是的,使用实体。如果我有这个:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE reports [
<!ENTITY title SYSTEM "title.xml">
<!ENTITY document1 SYSTEM "document1.xml">
]>
<reports>
    &title;
    &document1;
</reports>

我有这个标题:

<blue_book>
    <title>I am the title of title</title>
</blue_book>

和document1.xml一样:

<blue_book>
    <title>I am the title of document 1</title>
</blue_book>

xpath // reports / blue_book / title产生:

系统ID:F:\ RenderX \ Demonstrations \ Tricks \ Image \ title.xml 描述:我是标题的标题 XPath位置:/ reports [1] / blue_book [1] / title [1] 出发地点:2:5 结束地点:2:43

系统ID:F:\ RenderX \ Demonstrations \ Tricks \ Image \ document1.xml 说明:我是文件1的标题 XPath位置:/ reports [1] / blue_book [2] / title [1] 出发地点:2:5 结束地点:2:48

count(// reports / blue_book)返回&#34; 2&#34;所以我没有测试过,但在我看来,你所做的一切都没有文件()

答案 1 :(得分:0)

好吧,如果你真的需要,你可以建立一个复合文档:

<xsl:variable name="composite">
 <composite>
   <xsl:for-each select="/reports/report">
     <xsl:copy-of select="document(@filename)/blue_book"/>
   </xsl:for-each>
 </composite>
</xsl:variable>

如果您遇到XSLT 1.0,则需要使用exslt:node-set($ composite)对此变量进行进一步处理。