Search in sources :

Example 6 with XdmNode

use of net.sf.saxon.s9api.XdmNode in project nifi by apache.

the class EvaluateXQuery method onTrigger.

@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) {
    final List<FlowFile> flowFileBatch = session.get(50);
    if (flowFileBatch.isEmpty()) {
        return;
    }
    final ComponentLog logger = getLogger();
    final Map<String, XQueryExecutable> attributeToXQueryMap = new HashMap<>();
    final Processor proc = new Processor(false);
    final XMLReader xmlReader;
    try {
        xmlReader = XMLReaderFactory.createXMLReader();
    } catch (SAXException e) {
        logger.error("Error while constructing XMLReader {}", new Object[] { e });
        throw new ProcessException(e.getMessage());
    }
    if (!context.getProperty(VALIDATE_DTD).asBoolean()) {
        xmlReader.setEntityResolver(new EntityResolver() {

            @Override
            public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
                return new InputSource(new StringReader(""));
            }
        });
    }
    final XQueryCompiler comp = proc.newXQueryCompiler();
    for (final Map.Entry<PropertyDescriptor, String> entry : context.getProperties().entrySet()) {
        if (!entry.getKey().isDynamic()) {
            continue;
        }
        final XQueryExecutable exp;
        try {
            exp = comp.compile(entry.getValue());
            attributeToXQueryMap.put(entry.getKey().getName(), exp);
        } catch (SaxonApiException e) {
            // should not happen because we've already validated the XQuery (in XQueryValidator)
            throw new ProcessException(e);
        }
    }
    final XQueryExecutable slashExpression;
    try {
        slashExpression = comp.compile("/");
    } catch (SaxonApiException e) {
        logger.error("unable to compile XQuery expression due to {}", new Object[] { e });
        session.transfer(flowFileBatch, REL_FAILURE);
        return;
    }
    final String destination = context.getProperty(DESTINATION).getValue();
    flowFileLoop: for (FlowFile flowFile : flowFileBatch) {
        if (!isScheduled()) {
            session.rollback();
            return;
        }
        final AtomicReference<Throwable> error = new AtomicReference<>(null);
        final AtomicReference<XdmNode> sourceRef = new AtomicReference<>(null);
        session.read(flowFile, new InputStreamCallback() {

            @Override
            public void process(final InputStream rawIn) throws IOException {
                try (final InputStream in = new BufferedInputStream(rawIn)) {
                    XQueryEvaluator qe = slashExpression.load();
                    qe.setSource(new SAXSource(xmlReader, new InputSource(in)));
                    DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
                    dfactory.setNamespaceAware(true);
                    Document dom = dfactory.newDocumentBuilder().newDocument();
                    qe.run(new DOMDestination(dom));
                    XdmNode rootNode = proc.newDocumentBuilder().wrap(dom);
                    sourceRef.set(rootNode);
                } catch (final Exception e) {
                    error.set(e);
                }
            }
        });
        if (error.get() != null) {
            logger.error("unable to evaluate XQuery against {} due to {}; routing to 'failure'", new Object[] { flowFile, error.get() });
            session.transfer(flowFile, REL_FAILURE);
            continue;
        }
        final Map<String, String> xQueryResults = new HashMap<>();
        List<FlowFile> childrenFlowFiles = new ArrayList<>();
        for (final Map.Entry<String, XQueryExecutable> entry : attributeToXQueryMap.entrySet()) {
            try {
                XQueryEvaluator qe = entry.getValue().load();
                qe.setContextItem(sourceRef.get());
                XdmValue result = qe.evaluate();
                if (DESTINATION_ATTRIBUTE.equals(destination)) {
                    int index = 1;
                    for (XdmItem item : result) {
                        String value = formatItem(item, context);
                        String attributeName = entry.getKey();
                        if (result.size() > 1) {
                            attributeName += "." + index++;
                        }
                        xQueryResults.put(attributeName, value);
                    }
                } else {
                    // if (DESTINATION_CONTENT.equals(destination)){
                    if (result.size() == 0) {
                        logger.info("Routing {} to 'unmatched'", new Object[] { flowFile });
                        session.transfer(flowFile, REL_NO_MATCH);
                        continue flowFileLoop;
                    } else if (result.size() == 1) {
                        final XdmItem item = result.itemAt(0);
                        flowFile = session.write(flowFile, new OutputStreamCallback() {

                            @Override
                            public void process(final OutputStream rawOut) throws IOException {
                                try (final OutputStream out = new BufferedOutputStream(rawOut)) {
                                    writeformattedItem(item, context, out);
                                } catch (TransformerFactoryConfigurationError | TransformerException e) {
                                    throw new IOException(e);
                                }
                            }
                        });
                    } else {
                        for (final XdmItem item : result) {
                            FlowFile ff = session.clone(flowFile);
                            ff = session.write(ff, new OutputStreamCallback() {

                                @Override
                                public void process(final OutputStream rawOut) throws IOException {
                                    try (final OutputStream out = new BufferedOutputStream(rawOut)) {
                                        try {
                                            writeformattedItem(item, context, out);
                                        } catch (TransformerFactoryConfigurationError | TransformerException e) {
                                            throw new IOException(e);
                                        }
                                    }
                                }
                            });
                            childrenFlowFiles.add(ff);
                        }
                    }
                }
            } catch (final SaxonApiException e) {
                logger.error("failed to evaluate XQuery for {} for Property {} due to {}; routing to failure", new Object[] { flowFile, entry.getKey(), e });
                session.transfer(flowFile, REL_FAILURE);
                session.remove(childrenFlowFiles);
                continue flowFileLoop;
            } catch (TransformerFactoryConfigurationError | TransformerException | IOException e) {
                logger.error("Failed to write XQuery result for {} due to {}; routing original to 'failure'", new Object[] { flowFile, error.get() });
                session.transfer(flowFile, REL_FAILURE);
                session.remove(childrenFlowFiles);
                continue flowFileLoop;
            }
        }
        if (DESTINATION_ATTRIBUTE.equals(destination)) {
            flowFile = session.putAllAttributes(flowFile, xQueryResults);
            final Relationship destRel = xQueryResults.isEmpty() ? REL_NO_MATCH : REL_MATCH;
            logger.info("Successfully evaluated XQueries against {} and found {} matches; routing to {}", new Object[] { flowFile, xQueryResults.size(), destRel.getName() });
            session.transfer(flowFile, destRel);
            session.getProvenanceReporter().modifyAttributes(flowFile);
        } else {
            // if (DESTINATION_CONTENT.equals(destination)) {
            if (!childrenFlowFiles.isEmpty()) {
                logger.info("Successfully created {} new FlowFiles from {}; routing all to 'matched'", new Object[] { childrenFlowFiles.size(), flowFile });
                session.transfer(childrenFlowFiles, REL_MATCH);
                session.remove(flowFile);
            } else {
                logger.info("Successfully updated content for {}; routing to 'matched'", new Object[] { flowFile });
                session.transfer(flowFile, REL_MATCH);
                session.getProvenanceReporter().modifyContent(flowFile);
            }
        }
    }
// end flowFileLoop
}
Also used : InputSource(org.xml.sax.InputSource) Processor(net.sf.saxon.s9api.Processor) AbstractProcessor(org.apache.nifi.processor.AbstractProcessor) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) HashMap(java.util.HashMap) XQueryCompiler(net.sf.saxon.s9api.XQueryCompiler) BufferedOutputStream(org.apache.nifi.stream.io.BufferedOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) Document(org.w3c.dom.Document) SAXException(org.xml.sax.SAXException) XdmValue(net.sf.saxon.s9api.XdmValue) BufferedInputStream(org.apache.nifi.stream.io.BufferedInputStream) StringReader(java.io.StringReader) List(java.util.List) ArrayList(java.util.ArrayList) OutputStreamCallback(org.apache.nifi.processor.io.OutputStreamCallback) BufferedOutputStream(org.apache.nifi.stream.io.BufferedOutputStream) XMLReader(org.xml.sax.XMLReader) TransformerException(javax.xml.transform.TransformerException) TransformerFactoryConfigurationError(javax.xml.transform.TransformerFactoryConfigurationError) FlowFile(org.apache.nifi.flowfile.FlowFile) PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) BufferedInputStream(org.apache.nifi.stream.io.BufferedInputStream) InputStream(java.io.InputStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) EntityResolver(org.xml.sax.EntityResolver) IOException(java.io.IOException) ComponentLog(org.apache.nifi.logging.ComponentLog) SaxonApiException(net.sf.saxon.s9api.SaxonApiException) XdmNode(net.sf.saxon.s9api.XdmNode) SAXException(org.xml.sax.SAXException) TransformerException(javax.xml.transform.TransformerException) ProcessException(org.apache.nifi.processor.exception.ProcessException) SaxonApiException(net.sf.saxon.s9api.SaxonApiException) TransformerConfigurationException(javax.xml.transform.TransformerConfigurationException) IOException(java.io.IOException) XQueryExecutable(net.sf.saxon.s9api.XQueryExecutable) ProcessException(org.apache.nifi.processor.exception.ProcessException) SAXSource(javax.xml.transform.sax.SAXSource) Relationship(org.apache.nifi.processor.Relationship) InputStreamCallback(org.apache.nifi.processor.io.InputStreamCallback) DOMDestination(net.sf.saxon.s9api.DOMDestination) Map(java.util.Map) HashMap(java.util.HashMap) XQueryEvaluator(net.sf.saxon.s9api.XQueryEvaluator) XdmItem(net.sf.saxon.s9api.XdmItem)

Example 7 with XdmNode

use of net.sf.saxon.s9api.XdmNode in project sirix by sirixdb.

the class XSLTEvaluator method call.

@Override
public OutputStream call() {
    final Processor proc = new Processor(false);
    final XsltCompiler comp = proc.newXsltCompiler();
    XsltExecutable exp;
    XdmNode source;
    try {
        final Configuration config = proc.getUnderlyingConfiguration();
        final NodeInfo doc = new DocumentWrapper(mSession, config);
        exp = comp.compile(new StreamSource(mStylesheet));
        source = proc.newDocumentBuilder().build(doc);
        if (mSerializer == null) {
            final Serializer out = new Serializer();
            out.setOutputProperty(Serializer.Property.METHOD, "xml");
            out.setOutputProperty(Serializer.Property.INDENT, "yes");
            out.setOutputStream(mOut);
            mSerializer = out;
        } else {
            mSerializer.setOutputStream(mOut);
        }
        final XsltTransformer trans = exp.load();
        trans.setInitialContextNode(source);
        trans.setDestination(mSerializer);
        trans.transform();
    } catch (final SaxonApiException e) {
        LOGGER.error("Saxon exception: " + e.getMessage(), e);
    } catch (final SirixException e) {
        LOGGER.error("TT exception: " + e.getMessage(), e);
    }
    return mOut;
}
Also used : DocumentWrapper(org.sirix.saxon.wrapper.DocumentWrapper) Processor(net.sf.saxon.s9api.Processor) Configuration(net.sf.saxon.Configuration) NodeInfo(net.sf.saxon.om.NodeInfo) StreamSource(javax.xml.transform.stream.StreamSource) XsltTransformer(net.sf.saxon.s9api.XsltTransformer) SirixException(org.sirix.exception.SirixException) XsltCompiler(net.sf.saxon.s9api.XsltCompiler) XdmNode(net.sf.saxon.s9api.XdmNode) SaxonApiException(net.sf.saxon.s9api.SaxonApiException) XsltExecutable(net.sf.saxon.s9api.XsltExecutable) Serializer(net.sf.saxon.s9api.Serializer)

Example 8 with XdmNode

use of net.sf.saxon.s9api.XdmNode in project jmeter by apache.

the class XPathUtil method putValuesForXPathInListUsingSaxon.

public static void putValuesForXPathInListUsingSaxon(String xmlFile, String xPathQuery, List<String> matchStrings, boolean fragment, int matchNumber, String namespaces) throws SaxonApiException, FactoryConfigurationError {
    // generating the cache key
    final ImmutablePair<String, String> key = ImmutablePair.of(xPathQuery, namespaces);
    // check the cache
    XPathExecutable xPathExecutable;
    if (StringUtils.isNotEmpty(xPathQuery)) {
        xPathExecutable = XPATH_CACHE.get(key);
    } else {
        log.warn("Error : {}", JMeterUtils.getResString("xpath2_extractor_empty_query"));
        return;
    }
    try (StringReader reader = new StringReader(xmlFile)) {
        // We could instantiate it once but might trigger issues in the future
        // Sharing of a DocumentBuilder across multiple threads is not recommended.
        // However, in the current implementation sharing a DocumentBuilder (once initialized)
        // will only cause problems if a SchemaValidator is used.
        net.sf.saxon.s9api.DocumentBuilder builder = PROCESSOR.newDocumentBuilder();
        XdmNode xdmNode = builder.build(new SAXSource(new InputSource(reader)));
        if (xPathExecutable != null) {
            XPathSelector selector = null;
            try {
                selector = xPathExecutable.load();
                selector.setContextItem(xdmNode);
                XdmValue nodes = selector.evaluate();
                int length = nodes.size();
                int indexToMatch = matchNumber;
                // In case we need to extract everything
                if (matchNumber < 0) {
                    for (XdmItem item : nodes) {
                        if (fragment) {
                            matchStrings.add(item.toString());
                        } else {
                            matchStrings.add(item.getStringValue());
                        }
                    }
                } else {
                    if (indexToMatch <= length) {
                        if (matchNumber == 0 && length > 0) {
                            indexToMatch = JMeterUtils.getRandomInt(length) + 1;
                        }
                        XdmItem item = nodes.itemAt(indexToMatch - 1);
                        matchStrings.add(fragment ? item.toString() : item.getStringValue());
                    } else {
                        if (log.isWarnEnabled()) {
                            log.warn("Error : {}{}", JMeterUtils.getResString("xpath2_extractor_match_number_failure"), indexToMatch);
                        }
                    }
                }
            } finally {
                if (selector != null) {
                    try {
                        selector.getUnderlyingXPathContext().setContextItem(null);
                    } catch (Exception e) {
                    // NOSONAR Ignored on purpose
                    // NOOP
                    }
                }
            }
        }
    }
}
Also used : InputSource(org.xml.sax.InputSource) XdmNode(net.sf.saxon.s9api.XdmNode) XMLStreamException(javax.xml.stream.XMLStreamException) SAXException(org.xml.sax.SAXException) TransformerException(javax.xml.transform.TransformerException) SaxonApiException(net.sf.saxon.s9api.SaxonApiException) IOException(java.io.IOException) SAXParseException(org.xml.sax.SAXParseException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) XdmValue(net.sf.saxon.s9api.XdmValue) SAXSource(javax.xml.transform.sax.SAXSource) XPathSelector(net.sf.saxon.s9api.XPathSelector) StringReader(java.io.StringReader) XPathExecutable(net.sf.saxon.s9api.XPathExecutable) XdmItem(net.sf.saxon.s9api.XdmItem)

Aggregations

XdmNode (net.sf.saxon.s9api.XdmNode)8 SaxonApiException (net.sf.saxon.s9api.SaxonApiException)5 IOException (java.io.IOException)3 StringReader (java.io.StringReader)3 TransformerException (javax.xml.transform.TransformerException)3 SAXSource (javax.xml.transform.sax.SAXSource)3 Processor (net.sf.saxon.s9api.Processor)3 XdmItem (net.sf.saxon.s9api.XdmItem)3 XdmValue (net.sf.saxon.s9api.XdmValue)3 InputSource (org.xml.sax.InputSource)3 SAXException (org.xml.sax.SAXException)3 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)2 XMLStreamException (javax.xml.stream.XMLStreamException)2 StreamSource (javax.xml.transform.stream.StreamSource)2 TinyBinary (lux.xml.tinybin.TinyBinary)2 Serializer (net.sf.saxon.s9api.Serializer)2 XPathExecutable (net.sf.saxon.s9api.XPathExecutable)2 XPathSelector (net.sf.saxon.s9api.XPathSelector)2 XsltCompiler (net.sf.saxon.s9api.XsltCompiler)2 XsltExecutable (net.sf.saxon.s9api.XsltExecutable)2