@Override
        public void endElement(final String uri,
                               final String localName,
                               final String qName) throws SAXException {
            LOGGER.info("endElement({}) called", localName);
            if (localName.equals("record")) {

                if (locator instanceof DSLocator) {
                    DSLocator dsLocator = (DSLocator) locator;
                    LOGGER.info("  [{}:{}] => [{}:{}]",
                            dsLocator.getLineNumber(),
                            dsLocator.getColumnNumber(),
                            dsLocator.getRecordEndLocator().getLineNumber(),
                            dsLocator.getRecordEndLocator().getColumnNumber());

                    textRanges.add(new TextRange(
                            DefaultLocation.of(dsLocator.getLineNumber(), dsLocator.getColumnNumber()),
                            DefaultLocation.of(
                                    dsLocator.getRecordEndLocator().getLineNumber(),
                                    dsLocator.getRecordEndLocator().getColumnNumber())));
                } else {
                    throw new RuntimeException("Expecting a DSLocator");
                }
            }
        }
@param input The string to extract the range from
@param from  Inclusive
@param to    Inclusive
@return The extracted string
stroom-pipeline/src/test/java/stroom/pipeline/xml/converter/ds3/TestDS3.java