Skip to content

Commit

Permalink
#1 XML.xslt() works
Browse files Browse the repository at this point in the history
  • Loading branch information
Yegor Bugayenko committed Oct 23, 2013
1 parent 3eb22ef commit 372d85c
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 15 deletions.
14 changes: 14 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,18 @@
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.maven.doxia</groupId>
<artifactId>doxia-module-markdown</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
10 changes: 10 additions & 0 deletions src/main/java/com/jcabi/xml/XML.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.xml.namespace.NamespaceContext;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import org.w3c.dom.Node;

/**
Expand Down Expand Up @@ -143,4 +145,12 @@ public interface XML {
*/
Node node();

/**
* Transform to another XML using provided XSL.
* @param xsl XSL stylesheet
* @return XML document
* @throws TransformerException If fails to transform
*/
XML xslt(Source xsl) throws TransformerException;

}
46 changes: 41 additions & 5 deletions src/main/java/com/jcabi/xml/XMLDocument.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
Expand All @@ -52,6 +56,7 @@
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.CharEncoding;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

Expand All @@ -66,8 +71,27 @@
*/
@EqualsAndHashCode(of = "dom")
@Loggable(Loggable.DEBUG)
@SuppressWarnings("PMD.ExcessiveImports")
public final class XMLDocument implements XML {

/**
* XPath factory.
*/
private static final XPathFactory XFACTORY =
XPathFactory.newInstance();

/**
* Transformer factory.
*/
private static final TransformerFactory TFACTORY =
TransformerFactory.newInstance();

/**
* Document Factory.
*/
private static final DocumentBuilderFactory DFACTORY =
DocumentBuilderFactory.newInstance();

/**
* Namespace context to use.
*/
Expand Down Expand Up @@ -217,13 +241,27 @@ public Node node() {
return this.dom;
}

@Override
@NotNull
public XML xslt(final Source xsl) throws TransformerException {
final Transformer trans = XMLDocument.TFACTORY.newTransformer(xsl);
final Document target;
try {
target = XMLDocument.DFACTORY.newDocumentBuilder().newDocument();
} catch (ParserConfigurationException ex) {
throw new IllegalStateException(ex);
}
trans.transform(new DOMSource(this.dom), new DOMResult(target));
return new XMLDocument(target, this.context);
}

@Override
@NotNull
public List<String> xpath(@NotNull final String query) {
final NodeList nodes = this.nodelist(query);
final List<String> items = new ArrayList<String>(nodes.getLength());
for (int idx = 0; idx < nodes.getLength(); ++idx) {
final short type = nodes.item(idx).getNodeType();
final int type = (int) nodes.item(idx).getNodeType();
if (type != Node.TEXT_NODE && type != Node.ATTRIBUTE_NODE
&& type != Node.CDATA_SECTION_NODE) {
throw new IllegalArgumentException(
Expand Down Expand Up @@ -277,7 +315,7 @@ public XML merge(@NotNull final NamespaceContext ctx) {
private NodeList nodelist(final String query) {
final NodeList nodes;
try {
final XPath xpath = XPathFactory.newInstance().newXPath();
final XPath xpath = XMLDocument.XFACTORY.newXPath();
xpath.setNamespaceContext(this.context);
nodes = (NodeList) xpath.evaluate(
query,
Expand All @@ -301,9 +339,7 @@ private NodeList nodelist(final String query) {
private static Node transform(final Source source) {
final DOMResult result = new DOMResult();
try {
TransformerFactory.newInstance()
.newTransformer()
.transform(source, result);
XMLDocument.TFACTORY.newTransformer().transform(source, result);
} catch (TransformerConfigurationException ex) {
throw new IllegalStateException(ex);
} catch (TransformerException ex) {
Expand Down
File renamed without changes.
4 changes: 4 additions & 0 deletions src/site/site.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
<item name="Test coverage" href="./cobertura/index.html"/>
<item name="Release History" href="./changes-report.html"/>
</menu>
<menu name="Examples">
<item name="Parsing XML" href="example-parsing.html"/>
<item name="XSL Transforming" href="example-xslt.html"/>
</menu>
<menu ref="reports"/>
</body>
</project>
36 changes: 26 additions & 10 deletions src/test/java/com/jcabi/xml/XMLDocumentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,18 @@
*/
package com.jcabi.xml;

import com.google.common.io.Files;
import com.rexsl.test.XhtmlMatchers;
import java.io.File;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.w3c.dom.Node;

/**
Expand All @@ -49,13 +51,6 @@
@SuppressWarnings("PMD.TooManyMethods")
public final class XMLDocumentTest {

/**
* Temporary folder.
* @checkstyle VisibilityModifier (3 lines)
*/
@Rule
public transient TemporaryFolder temp = new TemporaryFolder();

/**
* XMLDocument can find nodes with XPath.
* @throws Exception If something goes wrong inside
Expand Down Expand Up @@ -101,7 +96,7 @@ public void findsWithXpathAndNamespaces() throws Exception {
*/
@Test
public void findsWithXpathWithCustomNamespace() throws Exception {
final File file = this.temp.newFile("temp-1.xml");
final File file = new File(Files.createTempDir(), "x.xml");
FileUtils.writeStringToFile(
file,
"<a xmlns='urn:foo'><b>\u0433!</b></a>",
Expand Down Expand Up @@ -210,4 +205,25 @@ public void preservesProcessingInstructions() throws Exception {
);
}

/**
* XMLDocument can make XSL transformations.
* @throws Exception If something goes wrong inside
*/
@Test
public void makesXslTransformations() throws Exception {
final String xsl = StringUtils.join(
"<xsl:stylesheet",
" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'",
" version='2.0'>",
"<xsl:template match='/'><done/>",
"</xsl:template></xsl:stylesheet>"
);
MatcherAssert.assertThat(
new XMLDocument("<?xml version='1.0'?><a/>").xslt(
new StreamSource(IOUtils.toInputStream(xsl, Charsets.UTF_8))
),
XhtmlMatchers.hasXPath("/done")
);
}

}

0 comments on commit 372d85c

Please sign in to comment.