XSLT 2.0结果文档

时间:2013-10-28 14:32:30

标签: xslt xslt-2.0

我正在尝试将大型XML书分成多个文件(按章节)。这个沙盒XML:

<?xml version="1.0" encoding="UTF-8"?>
<book>
    <chapter id='1'>Chapter 1</chapter>
        <p>Highly random content.</p>
        <div>foo</div>
        <blockquote>Bar</blockquote>
    <chapter id='2'>Chapter 2</chapter>
        <div>
          <p>p in <i>italicized div</i>!</p>
        </div>
        <p>Content.</p>
    <chapter id='3'>Chapter 3</chapter>
       <blockquote>foo</blockquote>
       <p>foo</p>
    <chapter id='4'>Chapter 4</chapter>
       <p>foo</p>
      <p>end of book</p>
</book>

此XSLT根据需要进行转换:

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>    
<xsl:template match="book">
    <xsl:for-each-group select="*" group-starting-with="chapter"> 
        <xsl:result-document href="{concat('/home/paul/t',@id,'.xhtml')}">
            <xsl:for-each select="current-group()[self::*]">
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </xsl:result-document>
    </xsl:for-each-group>
</xsl:template>

问题。当我将XSLT应用于更复杂的生产文档时,它不起作用。我把源文档放在这里..但它太大了,客户可能不喜欢这样。

我很困惑为什么它不起作用。它不是像沙盒测试那样每章创建一个文件,而是制作一个大文件。怀疑问题可能与文件名中的@id有关。在生产文档上,@id出现空值。当我真的想要t.xhtml的多个文件时,结果文件名称为t --id of the chapter-- .xhtml,其中包含整本书。

任何提示在哪里看?有没有一种方法可以使上面的代码更加安静,以适应不同的文档复杂性(我认为这是我的问题......从简单概念到生产的转变引入了一些我没有抓到的东西,也许一些更严格的代码会有所帮助)

2 个答案:

答案 0 :(得分:1)

关于如何使代码更具弹性的问题,您可以尝试检查输入文件中最明显的错误,这会导致XSLT进程出错或至少产生无法使用的输出:

  • 在第一个<chapter>
  • 之前检查其他标签
  • 检查<chapter>没有@id
  • 使用非唯一<chapter>
  • 检查@id

以下XSLT将执行这些检查并发出警告。否则它将产生输出文件。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />

    <xsl:strip-space elements="*"/>    

    <xsl:template match="book">

      <xsl:variable name="chapter_ids" >
        <xsl:for-each-group select="chapter" group-by="@id">
          <count_me/>
        </xsl:for-each-group>
      </xsl:variable>

      <xsl:choose>

        <xsl:when test="name(*[1]) != 'chapter'">
          <xsl:message>The book does not start with chapter! --- Aborting</xsl:message>
        </xsl:when>

        <xsl:when test="count(chapter[normalize-space(@id) = '']) > 0">
          <xsl:message>The book contains chapters without chapter ids! - Aborting</xsl:message>
        </xsl:when>

        <xsl:when test="count(chapter) &gt; count($chapter_ids/count_me)">
          <xsl:message>The book has more chapters (<xsl:value-of select="count(chapter)"/>) than chapter ids (<xsl:value-of select="count($chapter_ids/count_me)"/>)! - Aborting</xsl:message>
        </xsl:when>

        <xsl:otherwise>

          <xsl:for-each-group select="*" group-starting-with="chapter"> 
            <xsl:result-document href="{concat('./t',@id,'.xhtml')}">
              <xsl:for-each select="current-group()[self::*]">
                <xsl:copy-of select="."/>
              </xsl:for-each>
            </xsl:result-document>
          </xsl:for-each-group>

        </xsl:otherwise>

      </xsl:choose>

    </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

您遇到的行为表明XPath group-starting-with="chapter"没有选择任何内容。我相信真实内容包含标签名称的差异。将单词chapter修改为任意文字会使问题在样本数据上重现。