XSLT 2.0含DocBook命名空间时多输出文件生成失败求助
解决DocBook命名空间下XSLT 2.0无法生成多HTML文件的问题
这个问题我太熟了——核心原因就是命名空间的匹配问题!
为什么加了命名空间就失效?
XPath的默认规则是:只匹配没有命名空间的元素。当你给<section>加上xmlns="http://docbook.org/ns/docbook"后,这个元素(包括它内部的<title>)就属于DocBook命名空间了,但你的XSLT里完全没处理这个命名空间,导致book/chapter/section根本选不到任何节点,自然不会生成任何输出文件。
两步搞定解决方案
你只需要修改XSLT的两个地方:
- 在
<xsl:stylesheet>根元素里声明DocBook命名空间,并绑定一个前缀(比如db) - 所有针对命名空间内元素的XPath选择器,都加上这个前缀
修改后的完整XSLT代码如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:db="http://docbook.org/ns/docbook" version="2.0"> <xsl:output method="text"/> <xsl:output method="html" indent="yes" name="html"/> <xsl:template match="/"> <xsl:for-each select="book/chapter/db:section"> <xsl:variable name="filename" select="concat('www/out/',@xml:id,'.html')" /> <xsl:value-of select="$filename" /> <!-- Creating --> <xsl:result-document href="{$filename}" format="html"> <html><body> <xsl:value-of select="db:title"/> </body></html> </xsl:result-document> </xsl:for-each> </xsl:template> </xsl:stylesheet>
额外说明
- 前缀可以随便取(比如换成
docbook也没问题),只要在整个XSLT里保持一致就行 - 注意
<title>继承了父元素的命名空间,所以必须写成db:title才能正确选中 - 你可以在模板里加一行
<xsl:value-of select="count(book/chapter/db:section)"/>,验证是否能正确统计到section的数量,确认选择器已经生效
用修改后的XSLT再运行你的Saxon命令,就能正常生成两个HTML文件了!
内容的提问来源于stack exchange,提问作者Seryoga
相关产品推荐
相关产品推荐

