代码之家  ›  专栏  ›  技术社区  ›  wasmachien Jon W

从Saxon转换获取序列化属性

  •  0
  • wasmachien Jon W  · 技术社区  · 6 年前

    我有以下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>
    

    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 回复  |  直到 6 年前
        1
  •  1
  •   Michael Kay    6 年前

    不幸的是,XSLT转换引擎和序列化程序之间的接口非常混乱。它在XSLT规范中很混乱,在JAXP中很混乱,在Saxon中也很混乱。这些年来我做了很多尝试来改进它,但它仍然很混乱。在saxon9.9中有一些变化,这些变化是新的和无辜的外观所必需的(在XSLT中,几乎是无用的) item-separator 属性,其效果是将单个项组合到文档树中(如果确实发生)必须发生在边界的序列化端,而不是转换端。

    saxon9.9s9api接口中的情况是(通常)Serializer对象对样式表中定义的序列化属性一无所知,它只知道通过serializerapi直接提供的那些属性。只有当转换器调用序列化程序来执行序列化时,这两组序列化属性才会合并。

    例外情况是使用 Xslt30Transformer.newSerializer() 创建序列化程序。在这种情况下,序列化程序是用unnamed中定义的属性初始化的 xsl:output 样式表中的声明,就好像它们是使用 serializer.setOutputProperty() .

    样式表中定义的序列化属性可以作为s9api的属性使用(尽管不是很直接) XsltExecutable . 这有一个方法 getUnderlyingCompiledStylesheet() 返回一个 PreparedStylesheet getDeclaredSerializationProperties() 返回在默认值(未命名)上定义的属性 xsl:输出 声明。还有一种方法 getOutputProperties(name) xsl:result-document )