我正在尝试将大型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
,其中包含整本书。
任何提示在哪里看?有没有一种方法可以使上面的代码更加安静,以适应不同的文档复杂性(我认为这是我的问题......从简单概念到生产的转变引入了一些我没有抓到的东西,也许一些更严格的代码会有所帮助)
答案 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) > 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
修改为任意文字会使问题在样本数据上重现。