Packages

  • package root

    This is the documentation for the Apache Daffodil Scala API.

    This is the documentation for the Apache Daffodil Scala API.

    Package structure

    org.apache.daffodil.sapi - Provides the classes necessary to compile DFDL schemas, parse and unparse files using the compiled objects, and retrieve results and parsing diagnostics

    org.apache.daffodil.udf - Provides the classes necessary to create User Defined Functions to extend the DFDL expression language

    org.apache.daffodil.runtime1.layers.api - Provides the classes necessary to create custom Layer extensions to DFDL.

    Definition Classes
    root
  • package org
    Definition Classes
    root
  • package apache
    Definition Classes
    org
  • package daffodil
    Definition Classes
    apache
  • package sapi

    Provides the classes necessary to compile DFDL schemas, parse and unparse files using the compiled objects, and retrieve results and parsing diagnostics

    Provides the classes necessary to compile DFDL schemas, parse and unparse files using the compiled objects, and retrieve results and parsing diagnostics

    Overview

    The Daffodil object is a factory object to create a Compiler. The Compiler provides a method to compile a provided DFDL schema into a ProcessorFactory, which creates a DataProcessor:

    val c = Daffodil.compiler()
    val pf = c.compileFile(file)
    val dp = pf.onPath("/")

    The DataProcessor provides the necessary functions to parse and unparse data, returning a ParseResult or UnparseResult, respectively. These contain information about the parse/unparse, such as whether or not the processing succeeded with any diagnostic information.

    The DataProcessor also provides two functions that can be used to perform parsing/unparsing via the SAX API. The first creates a DaffodilParseXMLReader which is used for parsing, and the second creates a DaffodilUnparseContentHandler which is used for unparsing.

    val xmlReader = dp.newXMLReaderInstance
    val unparseContentHandler = dp.newContentHandlerInstance(output)

    The DaffodilParseXMLReader has several methods that allow one to set properties and handlers (such as ContentHandlers or ErrorHandlers) for the reader. One can use any contentHandler/errorHandler as long as they extend the org.xml.sax.ContentHandler and org.xml.sax.ErrorHandler interfaces respectively. One can also set properties for the DaffodilParseXMLReader using DaffodilParseXMLReader.setProperty.

    The following properties can be set as follows:

    The constants below have literal values starting with "urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:sax:" and ending with "BlobDirectory", "BlobPrefix" and "BlobSuffix" respectively.

    xmlReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBDIRECTORY,
     Paths.get(System.getProperty("java.io.tmpdir"))) // value type: java.nio.file.Paths
    xmlReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBPREFIX, "daffodil-sax-") // value type String
    xmlReader.setProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_BLOBSUFFIX, ".bin") // value type String

    The properties can be retrieved using the same variables with DaffodilParseXMLReader.getProperty and casting to the appropriate type as listed above.

    The following handlers can be set as follows:

    xmlReader.setContentHandler(contentHandler)
    xmlReader.setErrorHandler(errorHandler)

    The handlers above must implement the following interfaces respectively:

    org.xml.sax.ContentHandler
    org.xml.sax.ErrorHandler

    The ParseResult can be found as a property within the DaffodilParseXMLReader using this uri: "urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:sax:ParseResult" or DaffodilParseXMLReader.DAFFODIL_SAX_URN_PARSERESULT

    In order for a successful unparse to happen, the SAX API requires the unparse to be kicked off by a parse call to any org.xml.sax.XMLReader implementation that has the DaffodilUnparseContentHandler registered as its content handler. To retrieve the UnparseResult, one can use DaffodilUnparseContentHandler.getUnparseResult once the XMLReader.parse run is complete.

    Parse
    Dataprocessor Parse

    The DataProcessor.parse method accepts input data to parse in the form of a InputSourceDataInputStream and an InfosetOutputter to determine the output representation of the infoset (e.g. Scala XML Nodes, JDOM2 Documents, etc.):

    val scalaOutputter = new ScalaXMLInfosetOutputter()
    val is = new InputSourceDataInputStream(data)
    val pr = dp.parse(is, scalaOutputter)
    val node = scalaOutputter.getResult

    The DataProcessor.parse method is thread-safe and may be called multiple times without the need to create other data processors. However, InfosetOutputter's are not thread safe, requiring a unique instance per thread. An InfosetOutputter should call InfosetOutputter.reset before reuse (or a new one should be allocated). For example:

    val scalaOutputter = new ScalaXMLInfosetOutputter()
    files.foreach { f => {
      outputter.reset
      val is = new InputSourceDataInputStream(new FileInputStream(f))
      val pr = dp.parse(is, scalaOutputter)
      val node = scalaOutputter.getResult
    }

    One can repeat calls to parse() using the same InputSourceDataInputStream to continue parsing where the previous parse ended. For example:

    val is = new InputSourceDataInputStream(dataStream)
    val scalaOutputter = new ScalaXMLInfosetOutputter()
    val keepParsing = true
    while (keepParsing && is.hasData()) {
      scalaOutputter.reset()
      val pr = dp.parse(is, jdomOutputter)
      ...
      keepParsing = !pr.isError()
    }
    SAX Parse

    The DaffodilParseXMLReader.parse method accepts input data to parse in the form of a InputSourceDataInputStream. The output representation of the infoset, as well as how parse errors are handled, are dependent on the content handler and the error handler provided to the DaffodilParseXMLReader. For example, the org.jdom2.input.sax.SAXHandler provides a JDOM representation, whereas other ContentHandlers may output directly to a java.io.OutputStream or java.io.Writer.

    val contentHandler = new SAXHandler()
    xmlReader.setContentHandler(contentHandler)
    val is = new InputSourceDataInputStream(data)
    xmlReader.parse(is)
    val pr = xmlReader.getProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_PARSERESULT)
    val doc = saxHandler.getDocument

    The DaffodilParseXMLReader.parse method is not thread-safe and may only be called again/reused once a parse operation is completed. This can be done multiple times without the need to create new DaffodilParseXMLReaders, ContentHandlers or ErrorHandlers. It might be necessary to reset whatever ContentHandler is used (or allocate a new one). A thread-safe implementation would require unique instances of the DaffodilParseXMLReader and its components. For example:

    val contentHandler = new SAXHandler()
    xmlReader.setContentHandler(contentHandler)
    files.foreach { f => {
      contentHandler.reset
      val is = new InputSourceDataInputStream(new FileInputStream(f))
      xmlReader.parse(is)
      val pr = xmlReader.getProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_PARSERESULT)
      val doc = saxHandler.getDocument
    }

    The value of the supported features cannot be changed during a parse, and the parse will run with the value of the features as they were when the parse was kicked off. To run a parse with different feature values, one must wait until the running parse finishes, set the feature values using the XMLReader's setFeature and run the parse again.

    One can repeat calls to parse() using the same InputSourceDataInputStream to continue parsing where the previous parse ended. For example:

    val is = new InputSourceDataInputStream(dataStream)
    val contentHandler = new SAXHandler()
    xmlReader.setContentHandler(contentHandler)
    val keepParsing = true
    while (keepParsing && is.hasData()) {
      contentHandler.reset()
      xmlReader.parse(is)
      val pr = xmlReader.getProperty(DaffodilParseXMLReader.DAFFODIL_SAX_URN_PARSERESULT)
      ...
      keepParsing = !pr.isError()
    }
    Unparse
    Dataprocessor Unparse

    The same DataProcessor used for parse can be used to unparse an infoset via the DataProcessor.unparse method. An InfosetInputter provides the infoset to unparse, with the unparsed data written to the provided java.nio.channels.WritableByteChannel. For example:

    val inputter = new ScalaXMLInfosetInputter(node)
    val ur = dp.unparse(inputter, wbc)
    SAX Unparse

    In order to kick off an unparse via the SAX API, one must register the DaffodilUnparseContentHandler as the contentHandler for an XMLReader implementation. The call to the DataProcessor.newContentHandlerInstance method must be provided with the java.nio.channels.WritableByteChannel, where the unparsed data ought to be written to. Any XMLReader implementation is permissible, as long as they have XML Namespace support.

    val is = new ByteArrayInputStream(data)
    val os = new ByteArrayOutputStream()
    val wbc = java.nio.channels.Channels.newChannel(os)
    val unparseContentHandler = dp.newContentHandlerInstance(wbc)
    val xmlReader = SAXParserFactory.newInstance.newSAXParser.getXMLReader
    xmlReader.setContentHandler(unparseContentHandler)
    try {
     xmlReader.parse(is)
    } catch {
     case _: DaffodilUnparseErrorSAXException => ...
     case _: DaffodilUnhandledSAXException => ...
    }

    The call to the XMLReader.parse method must be wrapped in a try/catch, as DaffodilUnparseContentHandler relies on throwing an exception to end processing in the case of anyerrors/failures. There are two kinds of errors to expect: DaffodilUnparseErrorSAXException, for the case when the UnparseResult.isError, and DaffodilUnhandledSAXException, for any other errors.

    In the case of an DaffodilUnhandledSAXException,DaffodilUnparseContentHandler.getUnparseResult will return null.

    try {
      xmlReader.parse(new InputSource(is))
    } catch {
      case _: DaffodilUnhandledSAXException => ...
      case _: DaffodilUnparseErrorSAXException => ...
    }
    val ur = unparseContentHandler.getUnparseResult
    Failures and Diagnostics

    It is possible that failures could occur during the creation of the ProcessorFactory, DataProcessor, or ParseResult. However, rather than throwing an exception on error (e.g. invalid DFDL schema, parse error, etc), these classes extend WithDiagnostics, which is used to determine if an error occurred, and any diagnostic information (see Diagnostic) related to the step. Thus, before continuing, one must check WithDiagnostics.isError. For example:

    val pf = c.compile(file)
    if (pf.isError()) {
      val diags = pf.getDiagnostics()
      diags.foreach { d =>
        System.out.println(d.toString())
      }
      return -1;
    }
    Saving and Reloading Parsers

    In some cases, it may be beneficial to save a parser and reload it. For example, when starting up, it may be quicker to reload an already compiled parser than to compile it from scratch. To save a DataProcessor:

    val dp = pf.onPath("/")
    dp.save(saveFile);

    And to restore a saved DataProcessor:

    val dp = Daffodil.reload(saveFile);

    And use like below:

    val pr = dp.parse(data);

    or

    val xmlReader = dp.newXMLReaderInstance
    ... // setting appropriate handlers
    xmlReader.parse(data)
    val pr = xmlReader.getProperty("...ParseResult")
    Definition Classes
    daffodil
  • package infoset

    Defines various classes used control the representation of the infoset for parse and unparse.

    Defines various classes used control the representation of the infoset for parse and unparse. Classes that extend InfosetOutputter are provided to the DataProcessor.parse method to deteremine how to output an infoset. These classes are not guaranteed to be thread-safe. Classes that extend InfosetInputter are provided to the DataProcessor.unparse method to determine how to read in an infoset. A new InfosetOutputter is required for each call to unparse().

    Definition Classes
    sapi
  • InfosetInputter
  • InfosetInputterProxy
  • InfosetOutputter
  • InfosetOutputterProxy
  • JDOMInfosetInputter
  • JDOMInfosetOutputter
  • JsonInfosetInputter
  • JsonInfosetOutputter
  • NullInfosetOutputter
  • ScalaXMLInfosetInputter
  • ScalaXMLInfosetOutputter
  • W3CDOMInfosetInputter
  • W3CDOMInfosetOutputter
  • XMLTextEscapeStyle
  • XMLTextInfosetInputter
  • XMLTextInfosetOutputter
c

org.apache.daffodil.sapi.infoset

ScalaXMLInfosetOutputter

class ScalaXMLInfosetOutputter extends InfosetOutputterProxy

InfosetOutputter to build an infoset represented as a scala.xml.Node

Linear Supertypes
InfosetOutputterProxy, InfosetOutputter, runtime1.infoset.InfosetOutputter, BlobMethodsMixin, AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. ScalaXMLInfosetOutputter
  2. InfosetOutputterProxy
  3. InfosetOutputter
  4. InfosetOutputter
  5. BlobMethodsMixin
  6. AnyRef
  7. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Instance Constructors

  1. new ScalaXMLInfosetOutputter()

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  5. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... ) @native()
  6. def endArray(array: InfosetArray): Unit

    Called by Daffodil internals to signify the end of an array of elements.

    Called by Daffodil internals to signify the end of an array of elements.

    Throws java.lang.Exception if there was an error and Daffodil should stop parsing

    array

    the array that is ended. Various fields of DIArray can be accessed to determine things like the name, namespace, etc.

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  7. def endComplex(complex: InfosetComplexElement): Unit

    Called by Daffodil internals to signify the end of a complex element.

    Called by Daffodil internals to signify the end of a complex element.

    Throws java.lang.Exception if there was an error and Daffodil should stop parsing

    complex

    the complex element that is ended. Various fields of DIComplex can be accessed to determine things like the nil, name, namespace, etc.

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  8. def endDocument(): Unit

    Called by Daffodil internals to signify the end of the infoset.

    Called by Daffodil internals to signify the end of the infoset.

    Throws java.lang.Exception if there was an error and Daffodil should stop parsing

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  9. def endSimple(diSimple: InfosetSimpleElement): Unit

    Called by Daffodil internals to signify the end of a simple element.

    Called by Daffodil internals to signify the end of a simple element.

    Throws java.lang.Exception if there was an error and Daffodil should stop parsing

    diSimple

    the simple element that is ended. Various fields of DISimple can be accessed to determine things like the value, nil, name, namespace, etc.

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  10. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  11. def equals(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  12. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  13. final def getBlobDirectory(): Path
    Definition Classes
    BlobMethodsMixin
  14. final def getBlobPaths(): Seq[Path]
    Definition Classes
    BlobMethodsMixin
  15. final def getBlobPrefix(): String
    Definition Classes
    BlobMethodsMixin
  16. final def getBlobSuffix(): String
    Definition Classes
    BlobMethodsMixin
  17. final def getClass(): Class[_]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  18. def getResult(): Node

    Get the scala.xml.Node representing the infoset created during a parse

    Get the scala.xml.Node representing the infoset created during a parse

    This function shuld only be called if ParseResult.isError() returns false

  19. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  20. val infosetOutputter: runtime1.infoset.ScalaXMLInfosetOutputter

    The InfosetOutputter to proxy infoset events to

    The InfosetOutputter to proxy infoset events to

    Definition Classes
    ScalaXMLInfosetOutputterInfosetOutputterProxy
  21. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  22. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  23. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  24. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  25. def reset(): Unit

    Reset the internal state of this InfosetOutputter.

    Reset the internal state of this InfosetOutputter. This should be called inbetween calls to the parse method.

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  26. final def setBlobAttributes(dir: Path, prefix: String, suffix: String): Unit
    Definition Classes
    BlobMethodsMixin
  27. final def setBlobPaths(paths: Seq[Path]): Unit
    Definition Classes
    BlobMethodsMixin
  28. def startArray(array: InfosetArray): Unit

    Called by Daffodil internals to signify the beginning of an array of elements.

    Called by Daffodil internals to signify the beginning of an array of elements.

    Throws java.lang.Exception if there was an error and Daffodil should stop parsing

    array

    the array that is started. Various fields of DIArray can be accessed to determine things like the name, namespace, etc.

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  29. def startComplex(complex: InfosetComplexElement): Unit

    Called by Daffodil internals to signify the beginning of a complex element.

    Called by Daffodil internals to signify the beginning of a complex element.

    Throws java.lang.Exception if there was an error and Daffodil should stop parsing

    complex

    the complex element that is started. Various fields of DIComplex can be accessed to determine things like the nil, name, namespace, etc.

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  30. def startDocument(): Unit

    Called by Daffodil internals to signify the beginning of the infoset.

    Called by Daffodil internals to signify the beginning of the infoset.

    Throws java.lang.Exception if there was an error and Daffodil should stop parsing

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  31. def startSimple(diSimple: InfosetSimpleElement): Unit

    Called by Daffodil internals to signify the beginning of a simple element.

    Called by Daffodil internals to signify the beginning of a simple element.

    Throws java.lang.Exception if there was an error and Daffodil should stop parsing

    diSimple

    the simple element that is started. Various fields of DISimple can be accessed to determine things like the value, nil, name, namespace, etc.

    Definition Classes
    InfosetOutputterProxyInfosetOutputter → InfosetOutputter
  32. final def synchronized[T0](arg0: ⇒ T0): T0
    Definition Classes
    AnyRef
  33. def toString(): String
    Definition Classes
    AnyRef → Any
  34. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  35. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  36. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws( ... ) @native()

Inherited from InfosetOutputterProxy

Inherited from InfosetOutputter

Inherited from runtime1.infoset.InfosetOutputter

Inherited from BlobMethodsMixin

Inherited from AnyRef

Inherited from Any

Ungrouped