XSLT Streaming Chained Transform

不打扰是莪最后的温柔 提交于 2019-12-08 03:15:23

问题


I am using Saxon EE to transform a very large document, using streaming transform. I now need to chain multiple XSLTs. How does one go about doing that ? When not streaming, I have used the XSLTTransformer class as destination, to do chained transforms. If I am not mistaken, I guess I cannot do that, as that would create a result tree as against result stream. Thanks, Ani


回答1:


Pipe the SAX output events of the 1st transform into the SAX input events of the 2nd transform.

I've attached some example Scala code which shows this.

Basically it kicks off the 2nd XSLT first, which behind the scenes invokes the 1st XSLT with the initial input document capturing the intermediate output which is then fed as the input to the 2nd XSLT in real time. Nice.

  • It uses JAXP interfaces, so no S9 API.
  • I've successfully tested it with a 1.2GB input XML file.

Hope this helps.

XSLT 3.0 rocks by the way! Good choice.

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 = {}
}


来源:https://stackoverflow.com/questions/43937700/xslt-streaming-chained-transform

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!