首页 文章

当输入XML没有匹配时,为什么XSLT处理器会产生一个空文件?

提问于
浏览
0

我正在使用XSLT 2.0(使用SaxonHE)将一些XML Schema文档转换为一组文本文件 . 假设我想为输入XSD中找到的每个xs:complexType输出一个不同的输出文件,我的模板会像下面一样松散

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<xsl:output method="text" />
	

	<xsl:template match="@*|node()">
		<xsl:apply-templates select="node()|@*" />
	</xsl:template>

	<xsl:template match="xs:complexType[@name]">
		<xsl:variable name="fileName" select="concat('target/',@name,'.txt')" />
		<xsl:result-document href="{$fileName}"><xsl:value-of select="$fileName"/></xsl:result-document>
	</xsl:template>
</xsl:stylesheet>

对于任何包含xs:complexType的至少一个元素的XSD,我得到的输出在'target / {$ fileName} .txt'中正确生成,并且在该过程中不会生成其他文件 .

当我使用不包含任何xs的XSD运行此转换时出现问题:complexType,处理器生成一个默认的空xml文件,其名称遵循$ .xml其中$ 是输入的名称文件 . (例如books.xsd被转换为books.xsd.xml) . 如果没有与我的转换选择的模板匹配,如何摆脱默认的xml文件?

我使用的处理器是SaxonHE9,但我得到了与其他人相同的结果 .

1 回答

  • 0

    Martin确定了原因:实际上XSLT 2.0规范要求至少有一个结果文档,因此如果没有创建二级结果文档,则创建主要结果,即使它是空的 . 这是一个非常令人费解的规则,但我认为一些WG成员认为XSLT 1.0兼容性需要它 .

    主结果具有由“基本输出URI”确定的文件名 . 从命令行处理整个目录时,每个转换的基本输出URI由输出目录的名称和输入文件名称的最后部分组成 .

    XSLT 3.0规范放松了这条规则 . 它说(非规范性地):

    在本规范的先前版本中,声明当初始模板或函数的原始结果是空序列时,当且仅当转换不生成次要结果时(即,如果它不生成),应生成结果树调用xsl:result-document) . 如果转换产生序列化结果,并且这些结果被写入持久存储,则该条款最有可能产生明显影响:结果是产生空主结果的转换将覆盖基本输出URI位置处的任何现有内容 . 并且只有当转换不产生其他输出时 . 提供与早期版本的XSLT向后兼容的处理器API必须遵守此行为,但不要求新的处理器API这样做 .

    Saxon暂时采取谨慎态度保留2.0行为,但这肯定值得再次考虑 .

相关问题