0

Building XML strings in Java

I had to build relatively simple XML strings from user input recently in a project and was trying to come up with a beautiful, elegant solution to do it. Naturally, manual string concatenation was out. It’s messy, brittle, and basically a nightmare to maintain. My next alternative was XMLBeans but I rejected as it was too heavyweight. I didn’t need to register a schema and it was simply too inefficient and a huge overkill to use XMLBeans to generate a straightforward XML string due to the amount of boilerplate required.

Another consideration was that I wanted to build the string in the style of fluent interfaces, such that one could simply tell if the string was well formed simply by eyeballing it. I thought of using VTD-XML, which was the XML parser being used in the project, but I couldn’t find any XML building capabilities, only parsing ones. I then settled on JDom as I’ve used it before as well as a new kid on the block, java-xmlbuilder (uses JAXP internally to build the DOM). With that, let’s see some code!

JDom version:

Element orderXml= new Element("ORDER").addContent(new Element
							("ORDER_DETAILS").addContent(new Element
									("ORDER_ID").setText(
										"123"))).addContent(new Element
							("SHOP_DETAILS").addContent(new Element
									("SHOP_TYPE").setText
										("ONLINE")).addContent(new Element
									("SHOP_COUNTRY").setText
										("SG")));

XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
StringWriter stringWriter = new StringWriter();
xmlOutputter.output(new Document(orderXml), stringWriter);
System.out.println(stringWriter.toString());

// JDom output
<?xml version="1.0" encoding="UTF-8"?>
<ORDER>
  <ORDER_DETAILS>
    <ORDER_ID>123</ORDER_ID>
  </ORDER_DETAILS>
  <SHOP_DETAILS>
    <SHOP_TYPE>ONLINE</SHOP_TYPE>
    <SHOP_COUNTRY>SG</SHOP_COUNTRY>
  </SHOP_DETAILS>
</ORDER>

java-xmlbuilder version:

XMLBuilder xmlBuilder =
			XMLBuilder.create("ORDER")
								.e("ORDER_DETAILS")
									.e("ORDER_ID")
										.t("123")
									.up()
								.up()
								.e("SHOP_DETAILS")
									.e("SHOP_TYPE")
										.t("ONLINE")
									.up()
									.e("SHOP_COUNTRY")
										.t("SG");

Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.INDENT, "yes");
outputProperties.put("{http://xml.apache.org/xslt}indent-amount", "2");
System.out.println(xmlBuilder.asString(outputProperties));

// java-xmlbuilder output
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ORDER>
  <ORDER_DETAILS>
    <ORDER_ID>123</ORDER_ID>
  </ORDER_DETAILS>
  <SHOP_DETAILS>
    <SHOP_TYPE>ONLINE</SHOP_TYPE>
    <SHOP_COUNTRY>SG</SHOP_COUNTRY>
  </SHOP_DETAILS>
</ORDER>

Needless to say, I decided to use java-xmlbuilder as I found it more readable and also, it’s more easier to write code in the style of fluent interfaces with it. With JDom, I had to really pay attention to the indentation and bracketing as the correct visual position of the elements do not necessarily mean that your XML is well-formed. Get the order of your method calls and your closing brackets mixed up and even though it looks right, the resulting string will be malformed.

For java-xmlbuilder, coding in the style of fluent interfaces comes naturally due to the API and the brackets are simple to match up. The really cool thing about this is that once you have finished adding items to a new element, you can call the up() method to retrieve the XMLBuilder node that represents the parent of the current node. If you balance every call to element() with a call to up(), you can write code that closely resembles the structure of the XML document you are creating.

Verdict: java-xmlbuilder

0

Fluent Interfaces

Been reading about fluent interfaces recently and I think it’s a really great way of making your code more readable. For those unfamiliar with the term, a fluent interface is basically a watered down DSL where you write chained method calls in a form resembling sentences, which makes the code more readable.

In an example taken from The Productive Programmer, a team is building an app dealing with train cars and each train car had a marketing description. Train cars have lots of rules and regulations
associated with them, so they had to ask their business analysts if they had the perfectly nuanced definition of the type of car they needed to test. The version they showed the analysts initially was:

Car car = new CarImpl();
MarketingDescription desc = new MarketingDescriptionImpl();
desc.setType("Box");
desc.setSubType("Insulated");
desc.setAttribute("length", "50.5");
desc.setAttribute("ladder", "yes");
desc.setAttribute("lining type", "cork");
car.setDescription(desc);

While this looks perfectly normal to a Java developer, their business analysts couldn’t grasp it and hated it. Since translation of business requirements into code inevitably increases the chances of errors in the understanding of requirements, the team rewrote the above code in the form of a fluent interface to mitigate the problem. The fluent interface looks like this:

Car car = Car.describedAs()
             .box()
             .length(50.5)
             .type(Type.INSULATED)
             .includes(Equipment.LADDER)
             .lining(Lining.CORK);

As it turns out, the business analysts liked this much better. Most of the boilerplate code required by Java convention was removed, and the implementation was simple. All the mutators returned this instead of void, allowing the team to create sentences by chaining the method calls together. The implementation of Car looked like the following:

public class Car {
      private MarketingDescription _desc;
      public Car() {
          _desc = new MarketingDescriptionImpl();
      }
      public static Car describedAs() {
          return new Car();
      }
      public Car box() {
          _desc.setType("box");
          return this;
      }
      public Car length(double length) {
          _desc.setLength(length);
          return this;
      }
      public Car type(Type type) {
          _desc.setType(type);
          return this;
      }
      public Car includes(Equipment equip) {
          _desc.setAttribute("equipment", equip.toString());
          return this;
      }
      public Car lining(Lining lining) {
          _desc.setLining(lining);
          return this;
      }
  }

Beautiful, isn’t it? Of course, by doing this, your POJO will no longer conform to the JavaBeans spec, which makes fluent interfaces iffy to use on classes that will interact with frameworks that rely on the class conforming to the spec.

Nevertheless, fluent interfaces are still a very viable coding style that can be used for internal classes that deal with heavily with business logic. It’s especially useful when your code will have to be paraded in front of non-technical analysts to ensure that the business requirements have been translated accurately to code. Sometimes, showing raw code to the people with the business knowledge is much better than writing reams and reams of functional specs and hours and hours of showcasing the UI.