Oops Null Pointer

Java programming related

Category Archives: XML

Quick guide to transforming XML with XSLT

As a reminder to myself for a quick pattern for transforming XML via XSLT:

Some setup:


public static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
public static final String XSL_HEADER = "<xsl:stylesheet version=\"1.0\" " +
    "xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">";
public static final String ID_XFORM = "<xsl:template match=\"@*|node()\"><xsl:copy>" +
    "<xsl:apply-templates select=\"@*|node()\"/></xsl:copy></xsl:template>";

public static final String TRANS_ATTR = "<xsl:template match=\"ATTR_PATH@ATTR_NAME\">" +
    "<xsl:attribute name=\"ATTR_NAME\">ATTR_VALUE</xsl:attribute></xsl:template>";
public static final String XSL_END = "</xsl:stylesheet>";
public static final String XFORM_ATTR_XSL = XML_HEADER + XSL_HEADER + ID_XFORM + TRANS_ATTR + XSL_END;

And a usage sample transforming an attribute’s value:

String xsl = XFORM_ATTR_XSL.replace("ATTR_PATH", "");
xsl = xsl.replace("ATTR_NAME", "myAttribute");
xsl = xsl.replace("ATTR_VALUE", "newValue");

ByteArrayInputStream xslInputStream = new ByteArrayInputStream(xsl.getBytes("UTF-8"));
FileInputStream xml = new FileInputStream(new File("myXmlFile");
InputStream transformedXml = null;

try {
    transformedXml = transformXml(xml, xslInputStream);
}
finally {
    if (xml != null) xml.close();
}

and the transform method:

private InputStream transformXml(InputStream xml, InputStream xsl) throws TransformerConfigurationException, TransformerException {

    TransformerFactory factory = new org.apache.xalan.processor.TransformerFactoryImpl();
    Transformer transformer = factory.newTransformer(new StreamSource(xsl));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    transformer.transform(new StreamSource(xml), new StreamResult(baos));
    return new ByteArrayInputStream(baos.toByteArray());
}
Advertisements

Capturing Integration Testing Input/Output with XStream

A co-worker was looking for a way to capture input and results during a debug session for certain scenarios that were occurring at run time. Ideally they were looking for a tool that could be used in Eclipse and capture parameters and return values from frames in the debug session and then be able to reuse those values in jUnit tests.

A quick search couldn’t find any tools that find the bill, but as a quick and dirty method you can use XStream in an Eclipse “Display” view to dump out input and return variables. Then in a jUnit test you unserialise the XML back into objects and tests the inputs against the results.

The XML format gives you two instant advantages:

  • No need to reconstruct the input / result objects from scratch (which can be difficult, especially in complex or legacy systems)
  • Easy tweaking of the the XML to get the results you want

A disadvantage is that if the objects structure changes then re-factoring tools will miss the XML data and the test may no longer work.

To use this technique:

  • Put XStream in your project classpath
  • Show the Display view in eclipse (Widnow->Show View-> Display)
  • Put breakpoints in the code to capture input and result objects
  • At a breakpoint run the following code in the Display view to serialise the objects to XML
(new com.thoughtworks.xstream.XStream()).toXML(someObjectToSerialise)
  • Save the XML to files and load the files into a jUnit test (say with Commons FileUtils.readFileToString())

If you know of any other tools to do this in a more automated fashion then let me know (it would be cool to do this with a few clicks via a plugin – even generate the test classes).