@Override
    public void startElement(final String uri, final String localName, final String qName, final Attributes atts)
            throws SAXException {
        Attributes newAtts = atts;

        depth++;

        if (depth == 2) {
            // Modify the attributes if this is an event element so that a
            // unique ID is inserted.
            final Long streamId = idEnrichmentExpectedIds.getStreamId();
            final long[] eventIds = idEnrichmentExpectedIds.getEventIds();
            if (streamId != null) {
                // This is a first level element.
                count++;

                String eventId;
                // If we are using this is search result output then we need to
                // get event ids from a list.
                if (eventIds != null) {
                    // Check we haven't found more events than we are expecting to extract.
                    if (count > eventIds.length) {
                        final String msg = "Expected " +
                                eventIds.length +
                                " events but extracted " +
                                count +
                                " from stream " +
                                streamId;

                        LOGGER.debug(() -> msg);
                        LOGGER.trace(() -> Arrays.toString(eventIds));
                        errorReceiverProxy.log(Severity.WARNING, null, getElementId(), msg, null);

                        // Double check for duplicated ids.
                        final Set<Long> duplicateSet = new HashSet<>();
                        boolean duplicate = false;
                        for (final long id : eventIds) {
                            if (!duplicateSet.add(id)) {
                                duplicate = true;
                                break;
                            }
                        }
                        if (duplicate) {
                            final String err = "Duplicate id found in event id list: " + Arrays.toString(eventIds);
                            LOGGER.error(() -> err);
                            errorReceiverProxy.log(Severity.ERROR, null, getElementId(), err, null);
                        }
                    }

                    final int index = (int) (count - 1);
                    eventId = String.valueOf(eventIds[index]);
                } else {
                    eventId = String.valueOf(count);
                }

                final AttributesImpl idAtts = new AttributesImpl(newAtts);

                // Remove any existing id attribute.
                int index = idAtts.getIndex(STREAM_ID);
                if (index != -1) {
                    idAtts.removeAttribute(index);
                }
                index = idAtts.getIndex(EVENT_ID);
                if (index != -1) {
                    idAtts.removeAttribute(index);
                }

                // Add the ids to the element.
                idAtts.addAttribute(URI, STREAM_ID, STREAM_ID, STRING, String.valueOf(streamId));
                idAtts.addAttribute(URI, EVENT_ID, EVENT_ID, STRING, eventId);

                newAtts = idAtts;
            }
        }

        super.startElement(uri, localName, qName, newAtts);
    }
Fired on start element.

@param uri       the Namespace URI, or the empty string if the element has no
                 Namespace URI or if Namespace processing is not being
                 performed
@param localName the local name (without prefix), or the empty string if
                 Namespace processing is not being performed
@param qName     the qualified name (with prefix), or the empty string if
                 qualified names are not available
@param atts      the attributes attached to the element. If there are no
                 attributes, it shall be an empty Attributes object. The value
                 of this object after startElement returns is undefined
@throws org.xml.sax.SAXException any SAX exception, possibly wrapping another exception
@see #endElement
@see org.xml.sax.Attributes
@see org.xml.sax.helpers.AttributesImpl
stroom-pipeline/src/main/java/stroom/pipeline/filter/IdEnrichmentFilter.java