2017-09-16 63 views
0

我使用XSLT 2.0(和SaxonHE)将一些XML Schema文档转换为一组文本文件。 让说,我想每个XS不同的输出文件:复杂类型的输入XSD发现,我的模板将LOOL像下面为什么当输入XML不匹配时XSLT处理器会产生一个空文件?

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

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

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

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

当我使用不包含任何xs:complexType的XSD运行此转换时,处理器会生成默认的空xml文件,其名称在$ {input_file} .xml后面,其中$ {input_file}是输入文件的名称。 (例如books.xsd转换为books.xsd.xml)。 如何摆脱那个默认的xml文件,当没有匹配我的转换选择的模板?

我使用的处理器是SaxonHE9,但我跟别人不一样的结果。

+0

那么究竟如何运行撒克逊人,在命令行(如何在命令行正好看),与Java或.NET(如何做你的Java或.NET代码的样子),有喜欢氧气的编辑器? –

+1

一般来说,https://www.w3。org/TR/xslt20 /#执行变换命令“当结果序列为空时,还会创建隐式结果树,前提是在转换过程中没有对xsl:result-document指令进行评估。隐式结果树将由没有子项的文档节点组成。“所以这可能是你不想要的时候得到最终结果的原因,尽管到目前为止你提供的细节并不能解释为什么你会得到你说的某个文件名。 –

+0

在命令行中调用撒克逊处理器(Java实现),如下所示: java -classpath saxon9he.jar net.sf.saxon.Transform -t -xsl:transform.xsl -s:./架构 -o: ./target 其中./schemas和./target都是目录,因为我希望处理器能够同时在多个输入文件上运行。 –

回答

0

马丁已经确定的原因:事实上XSLT 2.0规范强制要求至少有一个结果文档,因此,如果没有创建辅助结果文档,然后创建了主要结果,即使它是空的。这是一个非常复杂的规则,但我认为一些工作组成员认为它需要XSLT 1.0兼容性。

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

的XSLT 3.0规范放宽了这一规则。它说(非规范性):

在本说明书的先前版本据指出,当最初的模板或功能的 原始结果是一个空序列, 结果树应,当且仅产生如果转换 不生成二级结果(即,如果它不调用 xsl:result-document)。如果转换生成序列化结果 并将这些结果写入持久性存储:效果为 ,则该规定最有可能具有明显的效果,则产生空主体结果的转换将覆盖基础上的任何现有内容输出URI位置if和 仅当转换不产生其他输出时。处理器的API 向后提供与早期版本的XSLT必须 尊重这种行为的兼容性,但对于新的处理器 的API,这样做没有任何要求。

撒克逊采取谨慎的方法来保持2.0的行为暂时,但它肯定值得再看一次。

相关问题