private void onXsltMessage(XdmNode content, boolean terminate, SourceLocator locator) {

        boolean foundMsg = false;
        String msg = "";
        Severity severity = Severity.ERROR;

        if (terminate) {
            // terminate trumps any severity element name (see below)
            severity = Severity.FATAL_ERROR;
        } else {
            // We may have elements (or any valid xml) inside <xsl:message></xsl:message>
            if (content != null && content.children() != null) {
                for (final XdmNode child : content.children()) {
                    if (child != null) {
                        final XdmNodeKind nodeKind = child.getNodeKind();
                        if (nodeKind == XdmNodeKind.TEXT) {
                            // Just text inside the msg
                            // <xsl:message>my message</xsl:message>
                            msg = child.getStringValue();
                            break;
                        } else if (nodeKind == XdmNodeKind.ELEMENT) {
                            // Found an element so try to use the elm name to set the severity, e.g.
                            // <xsl:message><error>my message</error></xsl:message>
                            // We don't care about the namespace
                            final String localElmName = NullSafe.get(child.getNodeName(), QName::getLocalName);
                            final Severity elmSeverity = Severity.getSeverity(localElmName);
                            if (elmSeverity != null) {
                                severity = elmSeverity;
                                msg = child.getStringValue();
                                foundMsg = true;
                                break;
                            }
                        }
                    }
                    // Not found on first child so just break out and use getStringValue
                    break;
                }
            }
        }
        if (!foundMsg) {
            msg = NullSafe.getOrElse(content, XdmNode::getStringValue, "");
        }

        if (NullSafe.isEmptyString(msg)) {
            msg = "NO MESSAGE";
        }

        errorReceiverProxy.log(
                severity,
                locationFactory.create(locator),
                getElementId(),
                msg,
                ErrorType.CODE,
                null);

        if (terminate) {
            throw ProcessException.create(
                    "Processing terminated due to <xsl:message terminate=\"yes\"> with message: " + msg);
        }
    }
This is called when <pre>{@code <xsl:message>my message</xsl:message>}</pre>
is used in the XSLT.
It will log a message to the errorReceiver as ERROR.
If the {@code terminate} attribute is used like so:
<pre>{@code <xsl:message terminate="yes">my message</xsl:message>}</pre>
then it will log it as FATAL and throw an exception which will immediately terminate processing
of the current stream part. Subsequent parts will still be processed.
You can do this to set the severity (namespace of the inner element does not matter):
<pre>{@code <xsl:message><info>my message</info></xsl:message>}</pre>
Setting {@code terminate} trumps any severity set.
stroom-pipeline/src/main/java/stroom/pipeline/filter/XsltFilter.java