从Saxon转换获取序列化属性

时间:2018-12-16 11:58:22

标签: java xslt saxon

我有以下XSL样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
   <xsl:output encoding="UTF-8" method="xml"/>
   <xsl:template match="/">
      <test/>
   </xsl:template>
</xsl:stylesheet>

我正在使用Saxon 9.9进行这种转换。

public String transform(InputStream input, InputStream stylesheet, OutputStream output){
  Processor p = new Processor(false);
  XsltCompiler c = p.newXsltCompiler();
  XsltExecutable e = c.compile(new StreamSource(stylesheet));
  Xslt30Transformer xf = e.load30();
  Serializer s = p.newSerializer(output);
  xf.transform(new StreamSource(input), s);
  return s.getOutputProperty(Serializer.Property.ENCODING));
}

我希望返回值是样式表中指定的“ UTF-8”,但是它返回null。 (序列化程序实例似乎根本没有任何属性。)为什么会这样,获取输出属性的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

不幸的是,XSLT转换引擎和序列化器之间的接口非常混乱。在XSLT规范中是混乱的,在JAXP中是混乱的,在Saxon中是混乱的。多年来,我已经做了很多尝试来改进它,但是仍然很混乱。 Saxon 9.9中进行了一些更改,这些更改是由新的且看起来无辜的(并且在XSLT中几乎无用)item-separator属性所必需的,其效果是将单个项目组合到文档树中(如果完全发生的话) )必须发生在边界的序列化方面,而不是转换方面。

Saxon 9.9 s9api界面中的情况是(通常)Serializer对象对样式表中定义的序列化属性一无所知,只知道直接通过Serializer API提供的那些。只有当Transformer调用Serializer进行序列化时,两组序列化属性才会组合在一起。

例外情况是使用Xslt30Transformer.newSerializer()创建序列化程序时。在那种情况下,序列化程序将使用样式表中未命名的xsl:output声明中定义的属性进行初始化,就像使用serializer.setOutputProperty()对其进行了显式设置一样。

样式表中定义的序列化属性可以(尽管不是很直接)作为s9api XsltExecutable的属性来使用。它具有方法getUnderlyingCompiledStylesheet()返回一个PreparedStylesheet对象,并且具有方法getDeclaredSerializationProperties()返回一个默认(未命名)xsl:output声明中定义的属性。还有一种方法getOutputProperties(name)返回命名输出格式的属性(如xsl:result-document中使用的那样)