XpathRenderer.java
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.esigate.xml;
import java.io.IOException;
import java.io.StringReader;
import java.io.Writer;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import nu.validator.htmlparser.common.DoctypeExpectation;
import nu.validator.htmlparser.dom.Dom2Sax;
import nu.validator.htmlparser.dom.HtmlDocumentBuilder;
import org.esigate.Renderer;
import org.esigate.impl.DriverRequest;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* XML renderer.
* <p>
* Applies optional XPath evaluation and XSLT transformation to the retrieved data.
*
* @author Stanislav Bernatskyi
*/
public class XpathRenderer implements Renderer {
private static final HtmlNamespaceContext HTML_NAMESPACE_CONTEXT = new HtmlNamespaceContext();
private static final XPathFactory X_PATH_FACTORY = XPathFactory.newInstance();
private final XPathExpression expr;
public XpathRenderer(String xpath) {
try {
XPath xpathObj = X_PATH_FACTORY.newXPath();
xpathObj.setNamespaceContext(HTML_NAMESPACE_CONTEXT);
this.expr = xpathObj.compile(xpath);
} catch (XPathExpressionException e) {
throw new ProcessingFailedException("failed to compile XPath expression", e);
}
}
/** {@inheritDoc} */
@Override
public void render(DriverRequest httpRequest, String src, Writer out) throws IOException {
try {
HtmlDocumentBuilder htmlDocumentBuilder = new HtmlDocumentBuilder();
htmlDocumentBuilder.setDoctypeExpectation(DoctypeExpectation.NO_DOCTYPE_ERRORS);
Document document = htmlDocumentBuilder.parse(new InputSource(new StringReader(src)));
NodeList matchingNodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
XhtmlSerializer serializer = new XhtmlSerializer(out);
Dom2Sax dom2Sax = new Dom2Sax(serializer, serializer);
for (int i = 0; i < matchingNodes.getLength(); i++) {
dom2Sax.parse(matchingNodes.item(i));
}
} catch (XPathExpressionException e) {
throw new ProcessingFailedException("Failed to evaluate XPath expression", e);
} catch (SAXException e) {
throw new ProcessingFailedException("Unable to parse source", e);
}
}
}