XML libraries in Java is a minefield. The amount of code required to manipulate and read XML is staggering, the risk of getting class path problems with different libraries is substantial and the handling of namespaces opens for a lot of confusion and errors. The worst thing is that the situation doesn’t seem to improve.A colleague made me aware of the JOOX library some time back. It’s a very good attempt to patch these problems. I found a few shortcomings with JOOX that made me want to explore alternatives and naturally I ended up writing my own library (as you do). I want the library to allow for Easy manipulation of XML, and in an episode of insufficient judgement, I named the library EAXY. It’s a really bad name, so I appreciate suggestions for improvement.Here is what I set out to solve: It should be easy to create fairly complex XML trees with Java code It should be straight-forward and fool-proof to use namespaces. (This is where JOOX failed me) It should easy to read values out of the XML structure. It should be easy to work with existing XML documents in the file structure or classpath The library should prefer throwing an exception over silently failing. As a bonus, I wanted to make it even easier to deal with (X)HTML, by adding convenience functions for this. 1. Creating an XML documentAn XML document is just a tree. How about if align the tree to the Java syntax tree. For example – lets say you wanted to programmatically wanted to construct some feedback on this article:<span style="color: #003399;">Element</span> email <span style="color: #339933;">=</span> Xml.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"message"</span>, Xml.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"recipients"</span>, Xml.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"recipent"</span>, Xml.<span style="color: #006633;">attr</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"type"</span>, <span style="color: #0000ff;">"email"</span><span style="color: #009900;">)</span>, Xml.<span style="color: #006633;">attr</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"role"</span>, <span style="color: #0000ff;">"To"</span><span style="color: #009900;">)</span>, Xml.<span style="color: #006633;">text</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"mailto:<a href="mailto:johannes@brodwall.com">johannes@brodwall.com</a>"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span>, Xml.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"recipent"</span>, Xml .<span style="color: #006633;">attr</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"type"</span>, <span style="color: #0000ff;">"email"</span><span style="color: #009900;">)</span>, Xml.<span style="color: #006633;">attr</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"role"</span>, <span style="color: #0000ff;">"Cc"</span><span style="color: #009900;">)</span>, Xml.<span style="color: #006633;">text</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"mailto:<a href="mailto:contact@brodwall.com">contact@brodwall.com</a>"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span>, Xml.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"subject"</span>, <span style="color: #0000ff;">"EAXY feedback"</span><span style="color: #009900;">)</span>, Xml.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"contents"</span>, <span style="color: #0000ff;">"I think this is an interesting library"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> Each element (Xml.el) has a tag name and can nest other elements, attributes (Xml.attr) or text (Xml.text). If the element only contains a text, we don’t even need to make the call to Xml.text. The syntax is optimized so that if you want to do a static import on Xml.* you can write code like this:<span style="color: #003399;">Element</span> email <span style="color: #339933;">=</span> el<span style="color: #009900;">(</span><span style="color: #0000ff;">"message"</span>, el<span style="color: #009900;">(</span><span style="color: #0000ff;">"recipients"</span>, el<span style="color: #009900;">(</span><span style="color: #0000ff;">"recipent"</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"type"</span>, <span style="color: #0000ff;">"email"</span><span style="color: #009900;">)</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"role"</span>, <span style="color: #0000ff;">"to"</span><span style="color: #009900;">)</span>, text<span style="color: #009900;">(</span><span style="color: #0000ff;">"mailto:<a href="mailto:johannes@brodwall.com">johannes@brodwall.com</a>"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span>, el<span style="color: #009900;">(</span><span style="color: #0000ff;">"recipent"</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"type"</span>, <span style="color: #0000ff;">"email"</span><span style="color: #009900;">)</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"role"</span>, <span style="color: #0000ff;">"cc"</span><span style="color: #009900;">)</span>, text<span style="color: #009900;">(</span><span style="color: #0000ff;">"mailto:<a href="mailto:contact@brodwall.com">contact@brodwall.com</a>"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span>, el<span style="color: #009900;">(</span><span style="color: #0000ff;">"subject"</span>, <span style="color: #0000ff;">"EAXY feedback"</span><span style="color: #009900;">)</span>, el<span style="color: #009900;">(</span><span style="color: #0000ff;">"content"</span>, <span style="color: #0000ff;">"I think this is an interesting library"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> 2. Reading XMLReading XML with Java code can be a challenge. The DOM API makes it extremely wordy to do anything at all. You an use XPath, but can be a bit too much on the compact side and when you do something wrong, the result is simply that you get an empty collection or a null value back. I think we can improve on this. Consider the following:<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">(</span>email.<span style="color: #006633;">find</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"recipients"</span>, <span style="color: #0000ff;">"recipient"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">texts</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> I step down the XML tree structure and get all the recipient email addresses of the previous message. But wait – running this code returns an empty list. EAXY allows us to avoid scratching our head over this:<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">(</span>email.<span style="color: #006633;">find</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"recipients"</span>, <span style="color: #0000ff;">"recipient"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">check</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>.<span style="color: #006633;">texts</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> Now I get the following exception: org.eaxy.NonMatchingPathException: Can't find {recipient} below [message, recipients]. Actual elements: [Element{recipent}, Element{recipent}] As you can see, we misspelled “recipent” in the message. Let’s get back to this problem later, but for now, let’s work around it to create something meaningful:<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">(</span><span style="color: #003399;">Element</span> recipient <span style="color: #339933;">:</span> email.<span style="color: #006633;">find</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"recipients"</span>, <span style="color: #0000ff;">"recipent"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">(</span><span style="color: #0000ff;">"to"</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">(</span>recipient.<span style="color: #006633;">attr</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"role"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">(</span>recipient.<span style="color: #006633;">text</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #009900;">}</span> <span style="color: #009900;">}</span> Again, I think this is about as fluent as Java’s syntax allows.3. Validation and namespacesSo, we had a message where one of the element names was misspelled. If you have an XSD document for the XML you’re using, you can validate the document against this. However, as you may get used to when it comes to Java XML libraries the act of performing this validation is quite well hidden behind complex API’s. So I’ve provided a little help: Xml.<span style="color: #006633;">validatorFromResource</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"mailmessage.xsd"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">validate</span><span style="color: #009900;">(</span>email<span style="color: #009900;">)</span><span style="color: #339933;">;</span> This reads the mailmessage.xsd from the classpath, which is the most common use case for me.Of course, most schemas don’t refer to elements in the empty namespace. When using validation, it’s common that we have to construct elements in a specific namespace. In most Java libraries for dealing with XML, this is hard and easy to get wrong, especially when namespaces are mixed. I’ve made namespaces into a primary feature of the Eaxy library:Namespace MSG_NS <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Namespace<span style="color: #009900;">(</span><span style="color: #0000ff;">"<a href="https://eaxy.org/test/mailmessage">https://eaxy.org/test/mailmessage</a>"</span>, <span style="color: #0000ff;">"msg"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #003399;">Element</span> email <span style="color: #339933;">=</span> MSG_NS.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"message"</span>, MSG_NS.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"recipients"</span>, MSG_NS.<span style="color: #006633;">el</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"recipient"</span>, MSG_NS.<span style="color: #006633;">attr</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"type"</span>, <span style="color: #0000ff;">"email"</span><span style="color: #009900;">)</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"role"</span>, <span style="color: #0000ff;">"cc"</span><span style="color: #009900;">)</span>, text<span style="color: #009900;">(</span><span style="color: #0000ff;">"mailto:<a href="mailto:contact@brodwall.com">contact@brodwall.com</a>"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> Notice that the “type” and the “role” attributes belong to different namespaces – a scenario that is especially hard to facilitate with other libraries. 4. TemplatingReading the XSD from the classpath inspired another usage: What if we have an XML document as a template in the classpath and then use Java-code to manipulate this document. This would be especially handy for XHTML:<span style="color: #003399;">Document</span> doc <span style="color: #339933;">=</span> Xml.<span style="color: #006633;">readResource</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"testdocument.html"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #003399;">Element</span> peopleElement <span style="color: #339933;">=</span> doc.<span style="color: #006633;">select</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"#peopleForm"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> peopleElement.<span style="color: #006633;">add</span><span style="color: #009900;">(</span>el<span style="color: #009900;">(</span><span style="color: #0000ff;">"input"</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"type"</span>, <span style="color: #0000ff;">"text"</span><span style="color: #009900;">)</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"name"</span>, <span style="color: #0000ff;">"firstName"</span><span style="color: #009900;">)</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"value"</span>, <span style="color: #0000ff;">"Johannes"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> peopleElement.<span style="color: #006633;">add</span><span style="color: #009900;">(</span>el<span style="color: #009900;">(</span><span style="color: #0000ff;">"input"</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"type"</span>, <span style="color: #0000ff;">"text"</span><span style="color: #009900;">)</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"name"</span>, <span style="color: #0000ff;">"lastName"</span><span style="color: #009900;">)</span>, attr<span style="color: #009900;">(</span><span style="color: #0000ff;">"value"</span>, <span style="color: #0000ff;">"Brodwall"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> This code reads the file testdocument.html from the classpath, selects the element with id “peopleForm” and adds two input elements to it.5. HTML convenienceIn the code above, we set the type, name and value attributes of HTML input elements. These are among the most frequently used attributes in HTML manipulation. To make this easier, I’ve added some convenience methods to Eaxy: peopleElement.<span style="color: #006633;">add</span><span style="color: #009900;">(</span>el<span style="color: #009900;">(</span><span style="color: #0000ff;">"input"</span><span style="color: #009900;">)</span> .<span style="color: #006633;">type</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"text"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">name</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"firstName"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">val</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Johannes"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> peopleElement.<span style="color: #006633;">add</span><span style="color: #009900;">(</span>el<span style="color: #009900;">(</span><span style="color: #0000ff;">"input"</span><span style="color: #009900;">)</span> .<span style="color: #006633;">type</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"text"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">name</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"lastName"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">val</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"Brodwall"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> A final case I wanted to optimize for is that of dealing with forms in HTML. Here’s some code that manipulates a form before that can be sent to the user.HtmlForm form <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HtmlForm<span style="color: #009900;">(</span>peopleElement<span style="color: #009900;">)</span><span style="color: #339933;">;</span> form.<span style="color: #006633;">set</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"firstName"</span>, <span style="color: #0000ff;">"Johannes"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> form.<span style="color: #006633;">set</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"lastName"</span>, <span style="color: #0000ff;">"Brodwall"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> doc.<span style="color: #006633;">writeTo</span><span style="color: #009900;">(</span>req.<span style="color: #006633;">getWriter</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> Here, I set the form contents directly. The code will throw an exception if a parameter name is misspelled, so it’s easy to ensure that you use it correctly.ConclusionI have five examples of how Eaxy can be used to do easily what’s hard to do with most XML libraries for Java: Create a document tree with pure Java code, read and manipulate individual parts of the XML tree, the use of namespace and validation, templating and manipulating (X)HTML documents and forms. Check out The library is not stable now, but for an XML library to be unstable may not be a very risky situation as most errors will be easy to detect long before production.I hope that you may find it useful to try and use this library in your code to deal with XML and (X)HTML manipulation. I’m hoping for some users who can help me iron out the bugs and make Eaxy even more easy to use.Oh, and do let me know if you come up with a better name. Java