Example usage for org.xml.sax ContentHandler characters

List of usage examples for org.xml.sax ContentHandler characters

Introduction

In this page you can find the example usage for org.xml.sax ContentHandler characters.

Prototype

public void characters(char ch[], int start, int length) throws SAXException;

Source Link

Document

Receive notification of character data.

Usage

From source file:org.syncope.core.report.UserReportlet.java

private void doExtractAttributes(final ContentHandler handler, final AbstractAttributableTO attributableTO,
        final Collection<String> attrs, final Collection<String> derAttrs, final Collection<String> virAttrs)
        throws SAXException {

    AttributesImpl atts = new AttributesImpl();
    if (!attrs.isEmpty()) {
        Map<String, AttributeTO> attrMap = attributableTO.getAttributeMap();

        handler.startElement("", "", "attributes", null);
        for (String attrName : attrs) {
            atts.clear();//from w  ww. ja  v a 2  s.co  m

            atts.addAttribute("", "", ATTR_NAME, XSD_STRING, attrName);
            handler.startElement("", "", "attribute", atts);

            if (attrMap.containsKey(attrName)) {
                for (String value : attrMap.get(attrName).getValues()) {
                    handler.startElement("", "", "value", null);
                    handler.characters(value.toCharArray(), 0, value.length());
                    handler.endElement("", "", "value");
                }
            } else {
                LOG.debug("{} not found for {}[{}]", new Object[] { attrName,
                        attributableTO.getClass().getSimpleName(), attributableTO.getId() });
            }

            handler.endElement("", "", "attribute");
        }
        handler.endElement("", "", "attributes");
    }

    if (!derAttrs.isEmpty()) {
        Map<String, AttributeTO> derAttrMap = attributableTO.getDerivedAttributeMap();

        handler.startElement("", "", "derivedAttributes", null);
        for (String attrName : derAttrs) {
            atts.clear();

            atts.addAttribute("", "", ATTR_NAME, XSD_STRING, attrName);
            handler.startElement("", "", "derivedAttribute", atts);

            if (derAttrMap.containsKey(attrName)) {
                for (String value : derAttrMap.get(attrName).getValues()) {
                    handler.startElement("", "", "value", null);
                    handler.characters(value.toCharArray(), 0, value.length());
                    handler.endElement("", "", "value");
                }
            } else {
                LOG.debug("{} not found for {}[{}]", new Object[] { attrName,
                        attributableTO.getClass().getSimpleName(), attributableTO.getId() });
            }

            handler.endElement("", "", "derivedAttribute");
        }
        handler.endElement("", "", "derivedAttributes");
    }

    if (!virAttrs.isEmpty()) {
        Map<String, AttributeTO> virAttrMap = attributableTO.getVirtualAttributeMap();

        handler.startElement("", "", "virtualAttributes", null);
        for (String attrName : virAttrs) {
            atts.clear();

            atts.addAttribute("", "", ATTR_NAME, XSD_STRING, attrName);
            handler.startElement("", "", "virtualAttribute", atts);

            if (virAttrMap.containsKey(attrName)) {
                for (String value : virAttrMap.get(attrName).getValues()) {
                    handler.startElement("", "", "value", null);
                    handler.characters(value.toCharArray(), 0, value.length());
                    handler.endElement("", "", "value");
                }
            } else {
                LOG.debug("{} not found for {}[{}]", new Object[] { attrName,
                        attributableTO.getClass().getSimpleName(), attributableTO.getId() });
            }

            handler.endElement("", "", "virtualAttribute");
        }
        handler.endElement("", "", "virtualAttributes");
    }
}

From source file:com.mirth.connect.plugins.datatypes.hl7v2.ER7Reader.java

private void handleField(ContentHandler contentHandler, String componentSeparator, String subcomponentSeparator,
        String segmentId, int fieldId, String field) throws SAXException {
    if ((field.indexOf(componentSeparator) > -1)
            || (handleSubcomponents && (field.indexOf(subcomponentSeparator) > -1))) {
        contentHandler.startElement("", segmentId + "." + fieldId, "", null);
        StringTokenizer componentTokenizer = new StringTokenizer(field, componentSeparator, true);
        handleComponents(contentHandler, componentSeparator, subcomponentSeparator, segmentId, fieldId, 1,
                componentTokenizer);/*w w  w.  j a v a2 s . c om*/
        contentHandler.endElement("", segmentId + "." + fieldId, null);
    } else {
        logger.trace("handling field: " + field);
        contentHandler.startElement("", segmentId + "." + fieldId, "", null);
        contentHandler.startElement("", segmentId + "." + fieldId + ".1", "", null);
        contentHandler.characters(field.toCharArray(), 0, field.length());
        contentHandler.endElement("", segmentId + "." + fieldId + ".1", null);
        contentHandler.endElement("", segmentId + "." + fieldId, null);
    }
}

From source file:com.mirth.connect.model.converters.NCPDPReader.java

private String parseHeader(String message, ContentHandler contentHandler) throws SAXException {
    String headerElementName = StringUtils.EMPTY;

    /*// w w w . j a va  2  s.  c  o  m
     * The first segment is always the Transaction header so we will process
     * it seperately.
     */
    if (message.indexOf(segmentDelimeter) != -1) {
        String header = message.substring(0, message.indexOf(segmentDelimeter));

        // handle a request (requests have a longer header than responses)
        if (header.length() > 40) {
            String transactionName = NCPDPReference.getInstance().getTransactionName(header.substring(8, 10));
            version = header.substring(6, 8);
            headerElementName = "NCPDP_" + version + "_" + transactionName + "_Request";

            contentHandler.startElement("", headerElementName, "", null);
            contentHandler.startElement("", "TransactionHeaderRequest", "", null);
            contentHandler.startElement("", "BinNumber", "", null);
            contentHandler.characters(header.toCharArray(), 0, 6);
            contentHandler.endElement("", "BinNumber", "");
            contentHandler.startElement("", "VersionReleaseNumber", "", null);
            contentHandler.characters(header.toCharArray(), 6, 2);
            contentHandler.endElement("", "VersionReleaseNumber", "");
            contentHandler.startElement("", "TransactionCode", "", null);
            contentHandler.characters(header.toCharArray(), 8, 2);
            contentHandler.endElement("", "TransactionCode", "");
            contentHandler.startElement("", "ProcessorControlNumber", "", null);
            contentHandler.characters(header.toCharArray(), 10, 10);
            contentHandler.endElement("", "ProcessorControlNumber", "");
            contentHandler.startElement("", "TransactionCount", "", null);
            contentHandler.characters(header.toCharArray(), 20, 1);
            contentHandler.endElement("", "TransactionCount", "");
            contentHandler.startElement("", "ServiceProviderIdQualifier", "", null);
            contentHandler.characters(header.toCharArray(), 21, 2);
            contentHandler.endElement("", "ServiceProviderIdQualifier", "");
            contentHandler.startElement("", "ServiceProviderId", "", null);
            contentHandler.characters(header.toCharArray(), 23, 15);
            contentHandler.endElement("", "ServiceProviderId", "");
            contentHandler.startElement("", "DateOfService", "", null);
            contentHandler.characters(header.toCharArray(), 38, 8);
            contentHandler.endElement("", "DateOfService", "");
            contentHandler.startElement("", "SoftwareVendorCertificationId", "", null);
            contentHandler.characters(header.toCharArray(), 46, 10);
            contentHandler.endElement("", "SoftwareVendorCertificationId", "");
            contentHandler.endElement("", "TransactionHeaderRequest", "");
        } else { // handle a response
            String transaction = NCPDPReference.getInstance().getTransactionName(header.substring(2, 4));
            version = header.substring(0, 2);
            headerElementName = "NCPDP_" + version + "_" + transaction + "_Response";

            contentHandler.startElement("", headerElementName, "", null);
            contentHandler.startElement("", "TransactionHeaderResponse", "", null);
            contentHandler.startElement("", "VersionReleaseNumber", "", null);
            contentHandler.characters(header.toCharArray(), 0, 2);
            contentHandler.endElement("", "VersionReleaseNumber", "");
            contentHandler.startElement("", "TransactionCode", "", null);
            contentHandler.characters(header.toCharArray(), 2, 2);
            contentHandler.endElement("", "TransactionCode", "");
            contentHandler.startElement("", "TransactionCount", "", null);
            contentHandler.characters(header.toCharArray(), 4, 1);
            contentHandler.endElement("", "TransactionCount", "");
            contentHandler.startElement("", "HeaderResponseStatus", "", null);
            contentHandler.characters(header.toCharArray(), 5, 1);
            contentHandler.endElement("", "HeaderResponseStatus", "");
            contentHandler.startElement("", "ServiceProviderIdQualifier", "", null);
            contentHandler.characters(header.toCharArray(), 6, 2);
            contentHandler.endElement("", "ServiceProviderIdQualifier", "");
            contentHandler.startElement("", "ServiceProviderId", "", null);
            contentHandler.characters(header.toCharArray(), 8, 15);
            contentHandler.endElement("", "ServiceProviderId", "");
            contentHandler.startElement("", "DateOfService", "", null);
            contentHandler.characters(header.toCharArray(), 23, 8);
            contentHandler.endElement("", "DateOfService", "");
            contentHandler.endElement("", "TransactionHeaderResponse", "");
        }
    }

    return headerElementName;
}

From source file:com.mirth.connect.plugins.datatypes.hl7v2.ER7Reader.java

private void handleComponent(ContentHandler contentHandler, String subcomponentSeparator, String segmentId,
        int fieldId, int componentId, String component) throws SAXException {
    if (handleSubcomponents && !subcomponentSeparator.isEmpty()
            && (component.indexOf(subcomponentSeparator) > -1)) {
        contentHandler.startElement("", segmentId + "." + fieldId + "." + componentId, "", null);
        // check if we have subcomponents, if so add them
        StringTokenizer subcomponentTokenizer = new StringTokenizer(component, subcomponentSeparator, true);
        handleSubcomponents(contentHandler, subcomponentSeparator, segmentId, fieldId, componentId, 1,
                subcomponentTokenizer);/*  w  w w .  j a v a  2  s. co  m*/
        contentHandler.endElement("", segmentId + "." + fieldId + "." + componentId, null);
    } else {
        logger.trace("handling component: " + component);
        // the naming is SEG.<field#>.<component#>
        contentHandler.startElement("", segmentId + "." + fieldId + "." + componentId, "", null);
        contentHandler.characters(component.toCharArray(), 0, component.length());
        contentHandler.endElement("", segmentId + "." + fieldId + "." + componentId, "");
    }
}

From source file:nl.architolk.ldt.processors.HttpClientProcessor.java

private void parseJSONObject(ContentHandler contentHandler, JSONObject json) throws SAXException {
    Object[] names = json.names().toArray();
    for (int i = 0; i < names.length; i++) {
        String name = (String) names[i];
        Object value = json.get(name);
        String safeName = name.replace('@', '_');
        contentHandler.startElement("", safeName, safeName, new AttributesImpl());

        if (value instanceof JSONObject) {
            parseJSONObject(contentHandler, (JSONObject) value);
        } else if (value instanceof JSONArray) {
            Iterator<?> jsonit = ((JSONArray) value).iterator();
            while (jsonit.hasNext()) {
                Object arrayValue = jsonit.next();
                if (arrayValue instanceof JSONObject) {
                    parseJSONObject(contentHandler, (JSONObject) arrayValue);
                } else {
                    String textValue = String.valueOf(arrayValue);
                    contentHandler.characters(textValue.toCharArray(), 0, textValue.length());
                }//  w ww . ja  v a 2 s. c  o  m
                //Array means repeating the XML node, so end the current node, and start a new one
                if (jsonit.hasNext()) {
                    contentHandler.endElement("", safeName, safeName);
                    contentHandler.startElement("", safeName, safeName, new AttributesImpl());
                }
            }
        } else {
            String textValue = String.valueOf(value);
            contentHandler.characters(textValue.toCharArray(), 0, textValue.length());
        }

        contentHandler.endElement("", safeName, safeName);
    }
}

From source file:FastStringBuffer.java

/**
 * Sends the specified range of characters as one or more SAX characters()
 * events./*from   w w w. ja v a  2 s.  com*/
 * Note that the buffer reference passed to the ContentHandler may be
 * invalidated if the FastStringBuffer is edited; it's the user's
 * responsibility to manage access to the FastStringBuffer to prevent this
 * problem from arising.
 * <p>
 * Note too that there is no promise that the output will be sent as a
 * single call. As is always true in SAX, one logical string may be split
 * across multiple blocks of memory and hence delivered as several
 * successive events.
 *
 * @param ch SAX ContentHandler object to receive the event.
 * @param start Offset of first character in the range.
 * @param length Number of characters to send.
 * @exception org.xml.sax.SAXException may be thrown by handler's
 * characters() method.
 */
public void sendSAXcharacters(org.xml.sax.ContentHandler ch, int start, int length)
        throws org.xml.sax.SAXException {

    int startChunk = start >>> m_chunkBits;
    int startColumn = start & m_chunkMask;
    if (startColumn + length < m_chunkMask && m_innerFSB == null) {
        ch.characters(m_array[startChunk], startColumn, length);
        return;
    }

    int stop = start + length;
    int stopChunk = stop >>> m_chunkBits;
    int stopColumn = stop & m_chunkMask;

    for (int i = startChunk; i < stopChunk; ++i) {
        if (i == 0 && m_innerFSB != null)
            m_innerFSB.sendSAXcharacters(ch, startColumn, m_chunkSize - startColumn);
        else
            ch.characters(m_array[i], startColumn, m_chunkSize - startColumn);

        startColumn = 0; // after first chunk
    }

    // Last, or only, chunk
    if (stopChunk == 0 && m_innerFSB != null)
        m_innerFSB.sendSAXcharacters(ch, startColumn, stopColumn - startColumn);
    else if (stopColumn > startColumn) {
        ch.characters(m_array[stopChunk], startColumn, stopColumn - startColumn);
    }
}

From source file:biz.taoconsulting.oxf.processor.converter.FromPdfConverter.java

/**
 * processBookmark gets called recursively for all nested bookmarks extracts
 * the bookmark and the text//from  w  w  w  . j a v  a  2s  .  c o m
        
 */
private void processBookmark(ContentHandler hd, PDDocument doc, PDOutlineItem curItem, String scope,
        int level) {
    // First we check on what page the bookmark is. If we can't retrieve the
    // page the bookmark can't be the outline we are looking for, however we
    // would process children (you never know)
    try {

        int curPageNo = getPageNumber(doc, curItem);

        if (curPageNo > -1) {

            AttributesImpl atts = new AttributesImpl();
            atts.addAttribute("", ATT_LEVEL, ATT_LEVEL, ATT_CDATA, Integer.toString(level));
            atts.addAttribute("", ATT_PAGE, ATT_PAGE, ATT_CDATA, Integer.toString(curPageNo));

            hd.startElement("", TAG_BOOKMARK, TAG_BOOKMARK, atts);

            // Write the properties of interest
            atts.clear();
            hd.startElement("", TAG_TITLE, TAG_TITLE, atts);
            String curTitle = curItem.getTitle();
            hd.characters(curTitle.toCharArray(), 0, curTitle.length());
            hd.endElement("", TAG_TITLE, TAG_TITLE);

            //write out the text associated with this bookmark
            // if the scope allows for that

            if (!scope.toLowerCase().equals(SCOPE_BOOKMARKSONLY)) {

                PDFTextStripper stripper = new PDFTextStripper();
                stripper.setStartBookmark(curItem);
                stripper.setEndBookmark(curItem);
                String textBetweenBookmarks = stripper.getText(doc);
                hd.startElement("", TAG_TEXT, TAG_TEXT, atts);
                textBetweenBookmarks = MassageTextResult(textBetweenBookmarks);
                hd.characters(textBetweenBookmarks.toCharArray(), 0, textBetweenBookmarks.length());
                hd.endElement("", TAG_TEXT, TAG_TEXT);

            }

        }
        // Now check the children
        PDOutlineItem child = curItem.getFirstChild();
        while (child != null) {
            processBookmark(hd, doc, child, scope, level + 1);
            logger.info("Child:" + child.getTitle());
            child = child.getNextSibling();
        }
        // Close the mark
        hd.endElement("", TAG_BOOKMARK, TAG_BOOKMARK);
    } catch (SAXException e) {
        logger.error(e);
        addErrorTagToOutput(hd, e.toString());
    } catch (IOException e) {
        logger.error(e);
        addErrorTagToOutput(hd, e.toString());
    } finally {
        // Nothing concluding to do
    }
}

From source file:FastStringBuffer.java

/**
 * Internal method to directly normalize and dispatch the character array.
 * This version is aware of the fact that it may be called several times
 * in succession if the data is made up of multiple "chunks", and thus
 * must actively manage the handling of leading and trailing whitespace.
 * /*from   w  w w  .j  a  va2 s.c  om*/
 * Note: The recursion is due to the possible recursion of inner FSBs.
 *
 * @param ch The characters from the XML document.
 * @param start The start position in the array.
 * @param length The number of characters to read from the array.
 * @param handler SAX ContentHandler object to receive the event.
 * @param edgeTreatmentFlags How leading/trailing spaces should be handled. 
 * This is a bitfield contining two flags, bitwise-ORed together:
 * <dl>
 * <dt>SUPPRESS_LEADING_WS</dt>
 * <dd>When false, causes leading whitespace to be converted to a single
 * space; when true, causes it to be discarded entirely.
 * Should be set TRUE for the first chunk, and (in multi-chunk output)
 * whenever the previous chunk ended in retained whitespace.</dd>
 * <dt>SUPPRESS_TRAILING_WS</dt>
 * <dd>When false, causes trailing whitespace to be converted to a single
 * space; when true, causes it to be discarded entirely.
 * Should be set TRUE for the last or only chunk.
 * </dd>
 * </dl>
 * @return normalization status, as in the edgeTreatmentFlags parameter:
 * <dl>
 * <dt>0</dt>
 * <dd>if this output did not end in retained whitespace, and thus whitespace
 * at the start of the following chunk (if any) should be converted to a
 * single space.
 * <dt>SUPPRESS_LEADING_WS</dt>
 * <dd>if this output ended in retained whitespace, and thus whitespace
 * at the start of the following chunk (if any) should be completely
 * suppressed.</dd>
 * </dd>
 * </dl>
 *
 * 
 * @exception org.xml.sax.SAXException Any SAX exception, possibly
 *            wrapping another exception.
 */
static int sendNormalizedSAXcharacters(char ch[], int start, int length, org.xml.sax.ContentHandler handler,
        int edgeTreatmentFlags) throws org.xml.sax.SAXException {
    boolean processingLeadingWhitespace = ((edgeTreatmentFlags & SUPPRESS_LEADING_WS) != 0);
    boolean seenWhitespace = ((edgeTreatmentFlags & CARRY_WS) != 0);
    int currPos = start;
    int limit = start + length;

    // Strip any leading spaces first, if required
    if (processingLeadingWhitespace) {
        for (; currPos < limit && XMLCharacterRecognizer.isWhiteSpace(ch[currPos]); currPos++) {
        }

        // If we've only encountered leading spaces, the
        // current state remains unchanged
        if (currPos == limit) {
            return edgeTreatmentFlags;
        }
    }

    // If we get here, there are no more leading spaces to strip
    while (currPos < limit) {
        int startNonWhitespace = currPos;

        // Grab a chunk of non-whitespace characters
        for (; currPos < limit && !XMLCharacterRecognizer.isWhiteSpace(ch[currPos]); currPos++) {
        }

        // Non-whitespace seen - emit them, along with a single
        // space for any preceding whitespace characters
        if (startNonWhitespace != currPos) {
            if (seenWhitespace) {
                handler.characters(SINGLE_SPACE, 0, 1);
                seenWhitespace = false;
            }
            handler.characters(ch, startNonWhitespace, currPos - startNonWhitespace);
        }

        int startWhitespace = currPos;

        // Consume any whitespace characters
        for (; currPos < limit && XMLCharacterRecognizer.isWhiteSpace(ch[currPos]); currPos++) {
        }

        if (startWhitespace != currPos) {
            seenWhitespace = true;
        }
    }

    return (seenWhitespace ? CARRY_WS : 0) | (edgeTreatmentFlags & SUPPRESS_TRAILING_WS);
}

From source file:com.mirth.connect.plugins.datatypes.hl7v2.ER7Reader.java

private void handleFieldOrRepetitions(ContentHandler contentHandler, String fieldSeparator,
        String componentSeparator, String subcomponentSeparator, String repetitionSeparator,
        String escapeCharacter, String segmentId, StringTokenizer fieldTokenizer) throws SAXException {
    int fieldId = 0;
    boolean atLastField = false;

    while (fieldTokenizer.hasMoreTokens()) {
        boolean enteredHeader = false;

        /*//  w ww . j  a  va2 s. com
         * Go through each element and add as new child under the segment
         * element
         */
        String field = fieldTokenizer.nextToken();

        // the naming is SEG.<field#>
        if (field.equals(fieldSeparator)) {
            if (atLastField) {
                contentHandler.startElement("", segmentId + "." + fieldId, "", null);
                contentHandler.endElement("", segmentId + "." + fieldId, "");
            }

            fieldId++;
            atLastField = true;
        } else {
            logger.trace("handling field or repetition: " + field);
            atLastField = false;

            // batch support
            if (segmentId.equals("MSH") || segmentId.equals("FHS") || segmentId.equals("BHS")) {
                enteredHeader = true;
            }

            if (enteredHeader && (fieldId == 1)) {
                contentHandler.startElement("", segmentId + "." + fieldId, "", null);
                contentHandler.characters(fieldSeparator.toCharArray(), 0, 1);
                contentHandler.endElement("", segmentId + "." + (fieldId), null);
                fieldId++;
                contentHandler.startElement("", segmentId + "." + fieldId, "", null);

                char[] specialCharacters;
                if (!subcomponentSeparator.isEmpty()) {
                    specialCharacters = new char[] { componentSeparator.charAt(0),
                            repetitionSeparator.charAt(0), escapeCharacter.charAt(0),
                            subcomponentSeparator.charAt(0) };
                } else if (!escapeCharacter.isEmpty()) {
                    specialCharacters = new char[] { componentSeparator.charAt(0),
                            repetitionSeparator.charAt(0), escapeCharacter.charAt(0), };
                } else {
                    specialCharacters = new char[] { componentSeparator.charAt(0),
                            repetitionSeparator.charAt(0), };
                }

                contentHandler.characters(specialCharacters, 0, specialCharacters.length);
                contentHandler.endElement("", segmentId + "." + (fieldId), null);
            } else if (enteredHeader && (fieldId == 2)) {
                // do nothing
            } else {
                if (handleRepetitions) {
                    handleFieldRepetitions(contentHandler, componentSeparator, repetitionSeparator,
                            subcomponentSeparator, segmentId, fieldId, field);
                } else {
                    handleField(contentHandler, componentSeparator, subcomponentSeparator, segmentId, fieldId,
                            field);
                }
            }
        }
    }

    if (atLastField) {
        contentHandler.startElement("", segmentId + "." + fieldId, "", null);
        contentHandler.endElement("", segmentId + "." + fieldId, "");
    }
}

From source file:com.mirth.connect.plugins.datatypes.delimited.DelimitedReader.java

public void parse(InputSource input) throws SAXException, IOException {

    // Parsing overview
    ////  w  w  w.ja  va  2  s .co m
    // The incoming stream is a single message which is a collection of one
    // or more records.
    // Each record is a collection of columns. Columns can be either fixed
    // width, or delimited.
    // Records are delimited.
    // Each record is assumed to contain the same number and type of
    // columns.
    //
    // The following user configurable options affect the behavior of the
    // parser:
    // o columnWidths The array of fixed column widths.
    // o columnDelimiter The characters that delimit (separate) the
    // columns.
    // o recordDelimiter The characters that delimit (separate) each
    // record.
    // o quoteToken The characters that are used to quote a column value.
    // o escapeWithDoubleQuote Iff true, embedded quotes are escaped with
    // two consecutive quotes.
    // Otherwise, the quote escape characters escape embedded quote
    // characters.
    // o quoteEscapeToken The characters used to escape a quote (or itself).
    // o ignoreCR Iff true, all incoming \r characters are ignored and not
    // processed.
    //
    // The following user configurable options affect the behavior of the
    // output:
    // o columnNames A list of column names (taken from either file header,
    // or supplied by user).
    BufferedReader in = new BufferedReader(input.getCharacterStream());

    // Start the document
    String documentHead = "delimited";
    ContentHandler contentHandler = getContentHandler();
    contentHandler.startDocument();

    // Output <delimited>
    contentHandler.startElement("", documentHead, "", null);

    // While the parser gets records from the message
    ArrayList<String> record;
    int recordNo = 1;
    while ((record = getRecord(in, null)) != null) {

        // Output <rowN>
        if (serializationProperties.isNumberedRows()) {
            contentHandler.startElement("", "row" + recordNo, "", null);
        } else {
            contentHandler.startElement("", "row", "", null);
        }

        // For each column
        for (int i = 0; i < record.size(); i++) {

            String columnName;
            if (serializationProperties.getColumnNames() != null
                    && i < serializationProperties.getColumnNames().length) {
                // User specified column name
                columnName = serializationProperties.getColumnNames()[i];
            } else {
                // Default column name
                columnName = "column" + (i + 1);
            }
            // Output <columnN>
            contentHandler.startElement("", columnName, "", null);

            // Output column value
            contentHandler.characters(record.get(i).toCharArray(), 0, record.get(i).length());

            // Output </columnN>
            contentHandler.endElement("", columnName, "");
        }

        // Output </rowN>
        if (serializationProperties.isNumberedRows()) {
            contentHandler.endElement("", "row" + recordNo, "");
        } else {
            contentHandler.endElement("", "row", "");
        }

        recordNo++;
    }

    // Output </delimited>
    contentHandler.endElement("", documentHead, "");

    // End the document
    contentHandler.endDocument();
}