# Use the XML Export API

The Java version of the API provides an interface to the core functionality of the C API. It provides two primary classes (`XmlExport` and `XmlExportReader`) that wrap the conversion functionality of the C API. The `XmlExport` class provides access to a family of methods called `convert`. The `XmlExportReader` class is a convenience class to help create SAX2-compliant applications.

The API is implemented in the `com.autonomy.api.export` package, which is contained in the `KeyView.jar` file. The jar file is in the `install``\javaapi` directory, where `install` is the path name of the Export installation directory.

For a full description of the Java API classes, see the Javadoc in the directory `install``\javaapi\javadoc`. Sample programs are provided to demonstrate the Java API. See Sample Programs.

You can access the Java API directly or by setting conversion options in template files, which are then passed to the API. For more information on template files, see Set Conversion Options.

For information on the C API, see the XML Export C Programming Guide.

## Input/Output Operations

In the Export Java API, input and output can be either a physical file accessed through a file path, or a Java stream. Depending on the `convert` method signature that you use, you can create the following conversion processes:

- convert an input file to output file

- convert an input file to an output stream

- convert an input stream to an output stream

- convert an input stream to an output file

You can set the input source by calling the `setInputSource` method, or when using the `convert` method. The latter takes the input source as one of its parameters. When you select a `convert` method, ensure that you use the correct signature for the desired input and output type.

NOTE: When the input source is from a Java stream, Export creates an internal buffer from the stream. If the input is a large file, Micro Focus recommends that you use a file as the input source.

## Convert Files

To convert files

1. Instantiate an `XmlExport` object.

       LicenseInfo license = new LicenseInfo("YOUR_ORGANIZATION", "YOUR_KEY");

       m_objExport = new XmlExport(license);

2. If you are using a template file to set the conversion options, call the `setIniFileName` method. It is recommended you set the full path to the template file.

       m_objExport.setIniFileName(m_iniFile);

   Conversion options are parameters that determine the content, structure, and appearance of the XML output. See Set Conversion Options.

3. If you are using the API to set the conversion options, create instances of the following classes:

   - `XmlOptionInfo`
   - `XmlTemplateInfo`
   - `XmlTOCOptionInfo`
   - `StyleMapping`
   - `XmlHeadingInfo`

   Conversion options are parameters that determine the content, structure, and appearance of the XML output. Set Conversion Options.

   Set the classes to the current `XmlExport` object using the following methods available in the `XmlExport` class:

   - `setOptionInfo`
   - `setTemplateInfo`
   - `setTOCOptionInfo`
   - `setStyleMapping`

   and the following method available in the `XmlTOCOptionInfo` class:

   - `setXmlHeadingInfo`

4. Set the location of the Export libraries by calling the `setExportDirectory` method. These are normally in the directory `install\OS\bin`, where `install` is the path name of the Export installation directory and `OS` is the name of the operating system.

       m_objExport.setExportDirectory(m_exportDirectory);

5. Open the source file by calling the `extOpenDocument` method. This call defines the parameters necessary to open a file for extraction.

       ExtOpenDocConfig odconfig = null;
       long extContextID = 0;
       odconfig = new ExtOpenDocConfig();
       odconfig.setUserName(m_userName);
       odconfig.setPassword(m_password);
       odconfig.setUserIDFile(m_userIDFile);
       odconfig.setExtractDirectory(m_extractDir);
       odconfig.setCreateRootNode(m_createRootNode);
       extContextID = m_objExport.extOpenDocument(inFile, odconfig);

6. Determine whether the main file is a container file (that is, whether it contains subfiles) by calling the `extGetMainFileInfo()` method.

       ExtMainFileInfo maininfo = null;
       maininfo = m_objExport.extGetMainFileInfo(extContextID);

7. If the call to `extGetMainFileInfo()` determined that the source file is a container file, proceed to Step 8; otherwise, proceed to Step 11.

8. Determine whether the subfile is itself a container (that is, whether it contains subfiles) by calling the `extGetSubFileInfo` method.

       ExtSubFileInfo subinfo = null;
       if(nSubFiles != 0)
       {
          for(int index = 0; index < nSubFiles; index++)
          {
          subinfo = m_objExport.extGetSubFileInfo(extContextID, index);
          ...
          }
       }

9. Extract the subfile by calling the `extExtractSubFile` method.

       ExtSubFileExtractConfig extconfig = null;
       extconfig = new ExtSubFileExtractConfig();
       extconfig.setCreateDirectory(true);
       extconfig.setOverWrite(true); extconfig.setExcludeMailHeader(m_excludeMailHeader);
       extinfo = m_objExport.extExtractSubFile(extContextID, index, extconfig);

10. If the call to `extGetSubFileInfo` determined that the subfile is a container file, repeat Step 5 through Step 9 until all subfiles are extracted; otherwise, proceed to Step 11.

11. Optionally, set the input source as either a file or input stream by calling the `setInputSource` method.

        if(m_inputMethod == Export.IO_METHOD_FILE)
        {
           //input as file
           m_objExport.setInputSource(m_extractDir + filename);
        }
        else
        {
           //input as stream
           File inf = new File(m_extractDir + filename);
           FileInputStream fis = new FileInputStream(inf);
           m_objExport.setInputSource(fis);
           fis.close();
        }

12. Set up an out-of-process session by calling the `startOOPSession` method. This initializes the out-of-process session, creates a Servant process, establishes a communication channel between the application thread and the Servant, and sends the data to the Servant.

        m_objExport.startOOPSession();

13. Convert the input and generate the output files by calling the `convertTo` method. You cannot use the `convert` methods that set the input source because the input source must be set before the out-of-process session is initialized. The `convertTo` method can only be called once in a single out-of-process session.

        if(m_outputMethod == Export.IO_METHOD_FILE)
        {
           //convert to a file
           m_objExport.convertTo(m_extractDir + filename + m_extension);
        }
        else
        {
           //convert to a stream
           File outf = new File(m_extractDir + filename + m_extension);
           FileOutputStream fos = new FileOutputStream(outf);
           m_objExport.convertTo(fos);
           fos.close();
        }

14. If you are converting additional files, terminate the out-of-process session by calling the `endOOPSession` method and setting the Boolean to `TRUE`. The Servant ends the current conversion session and releases the source data and session resources.

    If you are not converting additional files, terminate the out-of-process session and the Servant process by calling `endOOPSession` and setting the Boolean to `FALSE`.

        if(i == (nSubFiles - 1))
        {
           m_keepServantAlive = false;
        }
        else
        {
           m_keepServantAlive = true;
        }
        m_objExport.endOOPSession(m_keepServantAlive);

15. Close the file by calling the `extCloseDocument()` method.

        m_objExport.extCloseDocument(extContextID);

16. Repeat Step 2 through Step 15 for additional source files.

17. Terminate the session and free allocated system resources by calling the `shutdownExport()` method.

          m_objExport.shutdownExport();

## Multithreaded Conversions

To ensure that multithreaded conversions are thread-safe, you must create a unique Export context for every thread by instantiating an `XmlExport` object. In addition, threads must not share context objects, and you must use the same context object for all API calls in the same thread. Creating a context object for every thread does not affect performance because the context object uses minimal resources.

For example, your Java code should have the following logic in a thread:

    m_objExport = new XmlExport(license);

    m_objExport.setIniFileName(m_iniFile);

    m_objExport.setExportDirectory(m_exportDir);

    m_objExport.extOpenDocument(inFile, odconfig);

    m_objExport.extGetMainFileInfo(extContextID)  /* container file */

    m_objExport.extGetSubFileInfo(extContextID, index);

    m_objExport.extExtractSubFile(extContextID, index, extconfig);

    m_objExport.startOOPSession();

    m_objExport.convertTo(outFile);

    m_objExport.endOOPSession(bKeepServantAlive TRUE);

    m_objExport.extCloseDocument();

    m_objExport.extOpenDocument(inFile, odconfig);

    m_objExport.extGetMainFileInfo(extContextID);  /* not a container file */

    m_objExport.startOOPSession();

    m_objExport.convertTo(outFile);

    m_objExport.endOOPSession(bKeepServantAlive TRUE);

    m_objExport.extCloseDocument();

    ...

## Use Methods in the XmlExportReader Class

To use the methods in the `XmlExportReader` class

1. Ensure that you have a SAX2-compatible XML parser installed on your Java class path. Refer to http://www.saxproject.org.

2. Create the `XmlExportReader` object. If you use the default constructor, set the `org.xml.sax.driver` system property. See `org.xml.sax.helpers.XMLReaderFactory.createXMLReader()` for details.

3. Create the `XmlExport` object. Configure it as described in Convert Files, and pass it to `XmlExportReader`.

4. Set the `ContentHandler` using `setContentHandler`, and `ErrorHandler` using `setErrorHandler` of your `XmlExportReader` to either the default or your own setting.

5. Set the location of the `Verity.dtd` by using `setDtdLocation`. This must be an absolute URI (Uniform Resource Identifier). If you do not set this, the `parse()` method will not work.

6. Call the methods that suits your needs.

### Example

    XmlExport objXmlExport = new XmlExport();
    XmlExportReader objXmlExportReader = new XmlExportReader();
    //use the customized handler "TestHandler"
    TestHandler handler = new TestHandler();
    objXmlExportReader.setContentHandler(handler);
    objXmlExportReader.setErrorHandler(handler);
    objXmlExport.setIniFileName(iniFile);
    objXmlExport.setExportDirectory(exportDir);
    objXmlExportReader.setXmlExport(objXmlExport);
    objXmlExportReader.setDtdLocation(dtdLocation);
    objXmlExportReader.parse(inpSr);

For sample code, see the directory `install\javaapi\sample`, where `install` is the path name of the Export installation directory.

## Use Callbacks

Some Export methods enable you to specify a callback, which is called to control the conversion while it is in progress. For example, you can specify a callback to report progress during the conversion.

To use callbacks

1. If you are using the `UserCBCallback` interface, include the `$USERCB` token in a member of `KVXMLTemplate`. For example, placing `"$USERCB=``my_callback``"` in `pszFirstH1Start` results in a callback at the point when `pszFirstH1Start` is processed. The user callback function is identified by the text assigned to `$USERCB`, which in this example is `my_callback`.

   NOTE: The callback identifier must be delimited by a trailing white space. For example, `"my_callback "`

   The `callback.ini` template file provides an example of how to use callback tokens. The file is in the `install``\javaapi\ini` directory. See Export Tokens for more information on tokens.

2. Implement the callback interfaces. The callback interfaces are:

   - `CallbackConstants`
   - `CallingContext`
   - `ContinueCallback`
   - `GetAnchorCallback`
   - `GetAuxOutputCallback`
   - `UserCBCallback`

   Sample implementations of the callback interfaces are in the `install``\javaapi\sample\com\verity\api\htmlexport` directory, where `install` is the path name of the Export installation directory.

3. Declare the objects of the callback procedures you are going to use, and pass them to your instance of `XmlExport`.

#### Example

    ContinueCallback cci = new ContinueCallbackImpl();
    GetAnchorCallback gaci = new GetAnchorCallbackImpl();
    GetAuxOutputCallback gaoci = new GetAuxOutputCallbackImpl();
    UserCBCallback ucbi = new UserCBCallbackImpl();
    CallingContext cContext = new CallingContextImpl();
    objXmlExport.setCallingContext(cContext);
    objXmlExport.setContinueCallback(cci);
    objXmlExport.setGetAnchorCallback(gaci);
    objXmlExport.setGetAuxOutputCallback(gaoci);
    objXmlExport.setUserCBCallback(ucbi);

## Before Running Your Application

Before running your application, set the library path using one of the following methods:

- On Windows, add the location of `xmlexport.dll` to the `PATH` environment variable.

- On Linux and Solaris, add the location of `libxmlexport.so` to the `LD_LIBRARY_PATH` environment variable.

- On AIX, add the location of `libxmlexport.a` to the `LIBPATH` environment variable. You can also specify the library path as a system property as follows:

      java -Djava.library.path=bin_directory ...

_FT_HTML5_bannerTitle.htm