Tag Archives: xml

Dynamic namespaces with XSLT and Java

Recently I had to implement an XSLT transformation for a project here. It didn’t seem too complicated at first, since XSLT is not an alien technology – actually, it is pretty simple to use / develop with.

The problem was that, in this particular scenario, we needed namespaces whose URIs were generated dynamically, on pre-defined prefixes. The first idea that comes to mind is to write something like this:

<xsl:attribute name="xmlns:ns">
  <xsl:value-of select="$dynamicURI"/>
</xsl:attribute>

BUT… you can’t do this. Namespaces can’t be declared as normal attributes; the command above is illegal and won’t be processed by your XLST processor – you will probably get an XSLT compilation error.

If you google this problem for a while (which I did) you will find a few workarounds to make dynamic namespaces work. They basically involve creating dummy elements and copying them around. I tried using such approach for some time, but it started to consume too much time to work, and the resulting XLST code was getting really ugly – which also means that I was getting upset with the problem and its solution.

So I decided to look for a better way, and I found out that you could do this:

<xsl:namespace name="ns" select="$dynamicURI"/>

Amazing! Easy! Beautiful! And it doesn’t work with the standard XSLT processor that comes with Java – even Java 6, which I am using. The problem is that this command is specific to XSLT 2.0, which doesn’t seem to be supported by the default XSLT processor that comes bundled with the JDK distribution.

Although I was trying to avoid using external libraries, I had to do it this time. I added Saxon to the project and added this simple line in the code before calling the transformation:

System.setProperty(
  "javax.xml.transform.TransformerFactory",
  "net.sf.saxon.TransformerFactoryImpl");

Of course, there are other, more maintainable, ways to change this property, but you get the idea. Now I have my nice XLST with dynamic namespaces working, in a nice, simple and readable fashion =D


Testing XML data in your unit tests with XMLUnit

Once upon a time I had to compare two pieces of XML data. And it was good.

Well, actually, it wasn’t. Comparing two sets of XML can be really tough. Initially, I considered doing so by hand. Bad, bad idea, because:

  • You can’t simply say xmlString.equals(xmlString2) – any white space, including those indentation of yours will make the test fail;
  • The same equals call mentioned above will never say that <mytag></mytag> is the same as <mytag/> – and it almost always is;
  • How would you consider namespaces at all in those circumstances?
  • To solve all of the problems above, you could parse the XML data and verify each node… manually. A whole lot of work.

equals is totally out of the game for the reasons mentioned above. And I’m too lazy to check manually each node of the XML data. Also, such verification would be very error prone.

A better solution is needed, and after some ‘googling’ around, I found XMLUnit. In summary, what it does is that manual verification… But well tested and guaranteed to work – it is a framework developed specifically with that purpose in mind.

This is how a JUnit test using XMLUnit looks like:

import org.junit.Test;
import static org.custommonkey.xmlunit.XMLAssert.*;

public class SampleJCrankyTest {
    @Test
    public void testXml() {
        // this test will pass =)
        asssertXMLEqual("<myxml></myxml>", "</myxml>");
    }
}

This code is using JUnit and, obviously, java – but they seem to be developing a .Net version as well, if you prefer that – its just not as complete as the Java version.

There is a lot of additional xml related features supported, so a look in the documentation is recommended. But concluding, if you need to make xml comparisons, please do yourself a favour and don’t even consider doing any kind of manual testing – go for XMLUnit.

Have you ever faced this kind of problem before? How did you solve it? Please leave a comment! =)


XML Handling in Scala

It is finally time to get back to Scala. In this post, lets cover briefly some of the support Scala has for handling XML data. This is impressive stuff, and more so if you are used to how complex this can be in Java, for example.

Lets start with a simple example. Lets imagine you are dealing with a legacy system that exposes user information in an XML file like this excerpt:

<users>
  <user>
    <name>Paulo</name>
    <country>Brasil</country>
    <website>http://www.jcranky.com</website>
  </user>
</users>

In Java it would take you a lot of code and some patience to get this file transformed into an entity object. At the very least, you would need to find some library and/or configure some kind of mapping. Now this is how you can do it in Scala:

// define the User entity class
case class User (name: String, country: String, website: String)

// create a new User instance, using the xml data
val user = new User((userXml \\ "name").text, (userXml \\ "country").text, (userXml \\ "website").text)

The case keyword above says that the User class is a bean – i.e. Scala will generate getters and setters for you, you will have a nice “toString” implementation, among other things.

If you want to try it yourself you can simply type the xml data in the scala interpreter and attribute it to a variable or constant, like the code bellow, and then use to code above to process it:

val userXml =
<users>
  <user>
    <name>Paulo</name>
    <country>Brasil</country>
    <website>http://www.jcranky.com</website>
  </user>
</users>

The only additional thing you have to do in order to allow Scala to understand the xml code is to add this import statement:

import scala.xml._

There are  two things happening in the xml handling above. First, userXml \\ “name” gets a NodeSeq for each name tag found. Then text gets the String representing the tag’s body, which can be passed to the User’s constructor.

Now, something is wrong here, right? If I left the code in the example as is, I will only be able to read ONE user! Ok, I hear you. Just add a foreach loop, like bellow, and you’re done:

// extract the user reading code to a function
def readUser(userXml: NodeSeq): User = {
  new User((userXml \\ "name").text, (userXml \\ "country").text, (userXml \\ "website").text)
}

// loop through all users found in the xml and print them
usersXml.foreach(userXml => println(readUser(userXml)))

Better now? =)

Do you see that foreach thing we used in the last example? Well, that is not a XML specific function. It is defined in the Scala Collection API. Since the XML support is built on top of the Scala Collection API, you can do to xml everything you do to collections.

In this example, I’m demonstrating very basic features. There is a lot more worth taking a look in the Scala xml libraries. We only covered xml reading, for example. Writing may come in another post =)


Follow

Get every new post delivered to your Inbox.