1

我正在使用 Saxon EE 使用流式转换来转换一个非常大的文档。我现在需要链接多个 XSLT。如何做到这一点?不流式传输时,我使用 XSLTTransformer 类作为目标,进行链式转换。如果我没记错的话,我想我不能这样做,因为这会创建一个结果树而不是结果流。谢谢,阿尼

4

1 回答 1

4

将第一个变换的 SAX 输出事件通过管道传输到第二个变换的 SAX 输入事件。

我附上了一些显示这一点的示例 Scala 代码。

基本上,它首先启动第二个 XSLT,它在幕后调用第一个 XSLT,初始输入文档捕获中间输出,然后将其作为输入实时输入到第二个 XSLT。好的。

  • 它使用 JAXP 接口,因此没有 S9 API。
  • 我已经用一个 1.2GB 的输入 XML 文件成功地测试了它。

希望这可以帮助。

顺便说一句,XSLT 3.0 摇滚!好的选择。

import javax.xml.transform.sax.{SAXResult, SAXSource}
import javax.xml.transform.stream.{StreamResult, StreamSource}
import javax.xml.transform.{Source, Transformer}

import com.saxonica.config.StreamingTransformerFactory
import org.xml.sax._
import org.xml.sax.helpers.XMLFilterImpl

object Main extends App
{
  val transformer1 = transformer("transform-1.xsl")
  val transformer2 = transformer("transform-2.xsl")

  val inputXML = "big.xml"

  transformer2.transform(
    new SAXSource(
      new Transformer1OutputReader(transformer1, new StreamSource(inputXML)),
      null
    ),
    new StreamResult("out.xml")
  )

  def transformer(xslt : String) =
    new StreamingTransformerFactory().newTransformer(new StreamSource(xslt))

}


class Transformer1OutputReader(
  transformer1 : Transformer,
  source1 : Source) extends XMLFilterImpl
{
  def parseImpl() =
  {
    println("parseImpl()")

    val inputToSecondXslt : ContentHandler = getContentHandler

    transformer1.transform(
      source1,
      new SAXResult(inputToSecondXslt)
    )
  }

  override def parse(input : InputSource) = parseImpl
  override def parse(systemId : String) = parseImpl
  override def setFeature(name: String, value: Boolean) : Unit = {}
}
于 2017-05-12T20:22:27.953 回答